欢迎各位兄弟 发布技术文章

这里的技术是共享的

You are here

宁皓网 webpack:模块打包 有大用

webpack 是一个模块打包工具。

封面摄影:Timothy Poulton

来自 https://ninghao.net/course/3443#info


准备

1安装 webpack 与准备项目


我们可以先在全局范围去安装一下 webpack,这样你在哪里都可以使用 webpack 命令了 .. npm install .. 安装的是 webpack .. 加上一个 global 选项 .. 

npm install webpack --global

表示在全局范围去安装一下 ..

npm install webpack-cli --g


因为版本不同,可以看看这个,宁皓的版本有点老了,这个东西版本更新太快


https://webpack.js.org/api/cli/

https://github.com/webpack/webpack-cli


完成以后输入 

webpack --help 

.. 会返回一些帮助信息 .. 下面我们假装去创建一个项目,然后试一下 webpack 这个工具...

进入你想保存项目的地方 .. 创建一个目录 .. 名字可以是 ninghao-webpack .. 再进入到这个目录的下面 ..

创建一个 package.json,也就是 npm 的配置文件 .. 可以使用 

npm init 

这个命令 ...

下面可以在项目的本地再去安装一下 webpack .. 

npm install webpack --save-dev

npm install webpack-cli --save-dev

 .. 保存到项目的开发依赖里 ..

然后用编辑器打开这个目录 ..

先去创建两个文件 .. 一个是 entry.js .. 简单的添加点代码 .. 用一个 document.getElementById,找到页面上的 app 这个 id 的元素 .. 然后设置一下它里面的文件 .. hello ~ ..

document.getElementById('app').textContent = "hello ~";

再创建一个 html 文件 .. 名字是 index.html .. 在它里面添加一个基本的 html 结构 .. 再添加一个 div 标签,上面添加一个 app 这个 id ..

然后再去链接一个 js 文件 .. 要链接的文件的名字是 bundle.js ..

这个文件一会儿我们会用 webpack 去生成 .. 它其实就是使用 webpack 打包以后生成的一个文件 ..

回到命令行 ... 确定位置是在项目所在的根目录 .. 然后输入 webpack .. 先指定一下要打包的入口 .. 这里就是当前目录下的 entry.js .. 

webpack entry.js bundle.js  (新版应该是 webpack entry.js -o bundle.js  )

然后是打包以后生成的文件的名字 .. 这里我们叫它 bundle.js .. 这个文件就是在 index.html 里面链接使用的那个 js 文件 ..

执行一下 .. 这样会在项目里面生成一个打包以后的文件 .. 就是这个 bundle.js .. 它里面有一些注释开头的代码 .. 这应该是 webpack 自己需要的一些东西 .. 再往下看,你会找到打包的 entry.js 这个文件里的内容 ..

下面我们再用浏览器打开项目下面的 index.html ... 在页面上,会显示一个 hello ~ ...

来自  https://ninghao.net/video/3445#info


使用

2)打包

在创建项目的时候,你需要按照某些特定的标准,把项目分割成不同的部分 .. 它们之间可以互相使用 .. 在使用 webpack 打包的时候,它会分析文件跟文件之间的依赖的关系 ..

我们先在项目再去创建一个 js 文件 .. 假设它是应用的一部分 .. 名字可以是 name.js .. 在这个文件里我们先用 commonjs 模块的标准去写一个模块 .. module.exports .. 这里就是简单的导出点文字 .. ninghao.net ..

打开 entry.js .. 假设在这个文件里需要刚才我们创建的 name.js 这个模块里提供的功能或者内容 .. commonJS 的模块可以这样导入进来 .. 添加个变量 .. 名字是 name .. 然后使用 require .. 导入 name.js 这个模块 .. 它的位置是在当前这个目录的下面 .. 名字是 name ..

在下面再使用一下导入进来的这个模块里面提供的内容 .. 加上一个 name .. 保存 ..

回到命令行 .. 执行一下 webpack 命令 .. 打开这个打包之后生成的 bundle.js .. 这回在这个文件里面,会包含 entry.js 文件里的东西,另外还有它依赖的一个模块 .. 就是 name.js 文件里的东西 ..

到浏览器上再看一下 .. 这里会显示 name 这个模块里的内容 .. webpack 在打包的时候,看到 entry.js 里面需要使用其它的模块 .. 它就会把这个模块来导入到打包以后生成的文件里面 ..

有问题可以看看   https://webpack.js.org/configuration/mode/


来自  https://ninghao.net/video/3447#info

3)使用 loader 转换文件


Webpack 默认只能处理 JavaScript .. 如果你打算用它处理其它的东西,比如 html,css  等等,你需要安装对应的 loader ..

webpack 里说的 loader 有点像是一种转换器 .. 它可以把资源从一种形式转换成另一种形式 .. 不过最终得到的还是 JavaScript ..

下面来看一下怎么去使用 loader ... 先在项目里创建一个 css 文件 .. 名字是 style.css .. 添加点样式 .. 设置一下页面的背景颜色 ..

然后打开 entry.js .. 如果你想在这里把刚才创建的 style.css 导入进来,就需要使用一下 loader .. 这里要用的是 css-loader ,用它处理 css 文件 .. 还需要一个 style-loader,它可以去应用在 css 文件里的样式 ..

进入到项目所在的目录 .. 使用 npm install .. 去安装一下 css-loader .. 还有 style-loader .. 把它们也保存到项目的开发依赖里 ...

npm install css-loader style-loader --save-dev


回到项目 .. 在这个 entry.js 里面,使用一个 require .. 把 style.css 导入进来 .. 在这里我们就需要使用一下刚才安装的那两个 loader,把它放到样式文件的前面 .. 一个是 style .. 后面要加上一个叹号 .. 接着再用一下 css 这个 loader .. 也需要加上一个叹号 ..

新版应该用  style-loader!   css-loader!

require('style-loader!css-loader!./style.css');

保存一下 .. 回到命令行 .. 重新再用 webpack 去打包一下 ..

再回到浏览器 .. 刷新 .. 页面的背景颜色会变成绿色 .. 因为现在生成的 bundle 里面,包含了我们定义的样式 ...

有问题可以看看   https://webpack.js.org/migrate/3/#automatic-loader-module-n

来自  https://ninghao.net/video/3448#info

4)配置文件:webpack.config.js

webpack 的配置文件是 webpack.config.js ,你可以在项目的根目录下去创建一个这样的文件,然后在里面可以描述一下让 webpack 做的一些事情 ..

下面我们就去创建一个这样的配置文件 .. 新建文件 .. 名字是 webpack.config.js .. 里面用一下 module.exports .. 导出一个对象 .. 先指定一下 entry .. 也就是要打包的入口文件 .. 我这里就是当前目录下的 entry.js 这个文件 ..

再添加一个 output 属性 .. 在它的里面就是打包以后生成的文件要放到哪里,叫什么 .. 它的值是一个对象 .. 里面先用一个 path 属性,指定一下文件的存储位置 .. 这里用一下 __dirname .. 表示跟这个文件在同一个目录的下面 .. 然后是 filename 属性 .. 它可以指定一下生成的文件的名字 .. 这里设置成 bundle.js ..

这就是一个 webpack 配置文件最基本的东西 ..

另外我们在项目里又使用了一下 style 还有 css 这两个 loader 去处理项目里用的 css 文件 .. 在这个配置文件里可以再去配置一下 .. 添加一个 module 属性 .. 表示要使用的模块 ..

在它里面添加一个 loaders .. 设置一下要使用的 loader ... 它的值是一个数组 .. 每个项目是一个对象 .. 添加一个 test 属性 .. 它的值是一个正则表示式 .. 意思就是看看文件的扩展名是不是 css .. 再用一个 loader 属性设置一下具体要使用的 loader .. 用一下 style .. 还有 css 这两个 loader ..

保存 .. 因为我们在配置文件里设置了一下处理 css 文件要使用的 loader .. 所以在这个 entry.js 里面,导入 css 文件的时候,就不需要指定处理它的 loader 了 .. 这里还少了一个分号 ... 保存一下 ..

回到命令行 ... 这次我们只需要在项目的根目录下执行一下 webpack 这个命令 .. 因为相关的配置我们在它的配置文件里都描述清楚了 ..

来自 https://ninghao.net/video/3449#info

5)使用 source-map

我们把应用打包以后,想要调试代码就需要用到 source map 这个东西 ..

先看不一不用它的样子 ... 打开浏览器的开发者工具 ... 找到 source 选项卡 ..

这里除了 index.html 以后,就只有一个 bundle.js .. 这个文件是打包以后的文件 .. 一般我们不太关心它里面到底是什么 .. 我们只需要关心自己写的代码就可以了 ..

下面我们先看一下使用 webpack 命令生成 sourcemap 的方法 .. 打开命令行工具 .. 在这个要执行的 webpack 命令里面面,加上一个 devtool 这个选项 .. 然后设置一下要使用的开发工具 .. 这里就是 source-map ..

webpack --devtool source-map

执行一下 .. 这样会把应用打包同时又会生成一个 sourcemap .. 就是这个 bundle.js.map ..

再回到浏览器 .. 刷新一下 .. 这回这里就会多了一个 webpack:// 它里面的 . 这个目录的下面会包含一些文件 .. 这些文件就是没打包之前的东西 ..

我们可以试一下 . 回到编辑器 .. 打开这个 name.js .. 在这里用一下 debugger; 意思就是,代码运行到这儿的时候就停一下 ..

保存 .. 再执行一下 webpack 命令 ..

回到浏览器 .. 刷新 .. 执行到 name.js 那个 debugger 的时候就会停止了 .. 注意现在打开的这个 js 文件 .. 是 name.js 这个文件 ...

这就是 sourcemap 的用处 ..

我们再去修改一下 webpack 的配置文件,让它去生成一个 sourcemap .. 这里添加一个 devtool .. 它的值设置成 source-map ..

这样直接执行 

webpack 

的时候,就会为打包文件生成一个 sourcemap ..

来自  https://ninghao.net/video/3450#info

6)webpack 与 babel:处理 es2015


webpack 可以跟 babel 放到一块儿用 .. 比如你要打包的项目里面用了一些 es2015 或者 react 的 jsx .. 这些东西你可能需要使用 babel 去转换一下 .. 然后再交给 webpack 去打包 ..

想在 webpack 里使用 babel 需要一个 babel-loader .. 先去安装一些东西 .. npm install .. 安装一下 babel-loader ..

如果你的项目里还没有安装 babel 也需要再去安装一下 babel .. 这里再安装一下 babel-core .. 这里再安装一个 es2015 这个插件预设 .. 因为我们要处理一下项目里的 es2015 的代码 ..

npm install  babel-core babel-preset-es2015 --save-dev 

npm install  babel-loader@7  --save-dev


把这些要安装的东西放到项目的开发依赖里 ..

回到编辑器 .. 创建一个 babel 的配置文件 .. 名字是 .babelrc .. 添加一个 presets .. 设置一下想要使用的预设 .. 添加一个 es2015 ..

然后编辑一下 webpack 的配置文件,设置一下什么样的文件需要使用 babel 这个 loader 去处理 .. 这里我想要的是所有的 .js 文件都用一下 babel-loader ..

有问题,可以见 下面网址

https://webpack.js.org/migrate/3/#automatic-loader-module-name-extension-removed


最后再测试一下看看 .. 打开 name.js .. 我们可以使用点 es2015 的写法 .. let name = 'ninghao.net' .. 然后再用一下标准的 JavaScript 模块的写法 .. 使用 export 导出模块需要导出的东西 .. 把 name 作为默认的东西导出来 ..

打开 entry.js .. 这里我们可以再用一下标准的导入模块的写法 .. 用一个 import 导入一个模块..导入进来的名字也是 name .. 要导入的是当前目录下的 name 这个模块 ..


这个样式表我们也可以换成 import ,把它导入进来 .. 保存 ..

回到命令行 .. 执行一下 webpack .. 提示 webpack 的配置里面有一个语法错误 .. 打开这个 webpack.config.js .. 这里少了一个逗号 ... 保存 .. 再回到命令行 .. 执行一下 webpack .. 完成以后 ..

再打开浏览器 .. 刷新 .. 一切正常 ..

来自  https://ninghao.net/video/3451#info


7)webpack-dev-server 的模块热替换


webpack-dev-server 这个东西可以给为我们生成一个开发用的服务器,在文件有变化的时候自动给我们打包,然后刷新页面 .. 它还有个模块热替换的功能 .. 就是它可以只替换有变化的地方 .. 不需要刷新整个页面 ... 这个功能有很多好处 ..

因为你在开发调试的时候,页面会有一些特定的状态,比如在文本框里输入的文字 .. 画的图形 .. 如果每次修改项目的文件都重新刷新页面会比较麻烦,你需要重新修改页面上的一些状态 ..

先去安装一些东西 .. npm install .. 我们可以先在全局范围安装一下 webpack-dev-server .. 用一个 --global 选项 ..

npm install webpack-dev-server --global 

然后在项目的本地再去安装一下 webpack-dev-server .. 保存到项目的开发依赖里 ..

npm install webpack-dev-server  --save-dev

完成以后执行一下 webpack-dev-server .. 加上一个 --inline 选项 .. 还有一个 --hot ... 这样可以自动刷新页面,还有使用 hot module replacement ,模块的热替换 ..

webpack-dev-server --inline --hot

它会给我们生成一个服务器的地方 .. localhost:8080 ... 在浏览器上打开这个地址 ..

open http://localhost:8080

再打开浏览器的控制台 ... 调整一下显示 ...

上面会显示一些文字 .. Waiting for update signal from WDS .. 正在等待来自 webpack dev server  ( 简称 WDS )的更新信号 ..

下面这行是 Hot module replacement enabled .. 模块热替换已经启用了 .. 因为在执行 webpack-dev-server 命令的时候,我们加上了一个 --hot 选项 ..

再去试一下这个功能 .. 打开 style.css .. 为了证明一下没有刷新整个页面,我们在页面上添加一个文本框 .. 打开这个 entry.js .. 先创建一个 input 元素 .. 交给 input 这个变量 ..

找到页面上的 app 这个 id 的元素 .. 在它里面添加一个元素 .. 这里就是刚才创建的 input ..

然后在页面上的这个文本框里输入点东西 ... 再回到 style.css .. 修改一下这个背景颜色 .. 保存 ..

你会看看保存一下,页面上的背景颜色就有变化 .. 但是我们在文本框里输入的文字仍然存在 .. 说明使用了热替换 .. 也就是只替换只变化的地方 .. 如果刷新整个页面的话,我们在文本框里输入的文字就会不见了 ..

来自  https://ninghao.net/video/3452#info


8)webpack 与 react + 模块热替换

创建一个 React 项目,我们可以使用 babel 去处理项目里的 es2015 的代码,还有 React 的 JSX ,然后用 webpack 打包,还想有一个模块热替换的功能。下面我们一起去为 React 项目准备一些工具 ...

进入到项目的根目录的下面 .. 先去安装点东西 .. npm install .. 先安装一下 babel-core .. 还需要两个插件预设 .. babel-preset-es2015 .. 还有 babel-preset-react .. 再安装一下 webpack ... 还有 webpack-dev-server .. 创建开发用的服务器 ..

再去安装两个 webpack 的 loader, babel-loader .. 它可以让我们在 webpack 里使用 babel 去处理文件 .. 因为我们还想使用 react 的模块热替换,所以还得去安装一下 react-hot-loader ..

npm install babel-core babel-preset-es2015 babel-preset-react webpack webpack-dev-server babel-loader react-hot-loader --save-dev

把它们都保存到项目的开发依赖里 ..

完成以后再去安装一下 react ... 还有 react-dom ..

npm install react react-dom --save

编辑一下 webpack 的配置文件 .. 在所有 js 文件里面,除了使用 baebl 这个 loader,再用一下 react-hot 这个 loader ..

{ test: /\.js$/, exclude: /node_modules/, loader: 'react-hot!babel' },   (应该是 react-hot-loader!babel-loader 吧   )

结合   https://webpack.js.org/migrate/3/#automatic-loader-module-name-extension-removed 和 react-hot-loader 的 README.md 可以得出下面的结果

 rules: [
          {
            test: /\.js$/,
            exclude:/node_modules/,
            use:['react-hot-loader/webpack','babel-loader'],
            // loader: "react-hot-loader!babel-loader"
          },


这里还需要再添加一个额外的东西 .. 用一个 exclude .. 排除不想使用 loader 的目录 .. 排除的是 node_modules 这个目录 ..

再配置一下 babel .. 打开 .babelrc 这个文件 ... 没有这个文件可以去创建一个 .. 这里除了要使用 es2015 这个预设以后,我们还要使用一下 react 这个预设 .. 保存 ..

再去改造一下项目里的代码,打开 name.js .. 在这个文件里我们可以去定义一个 React 组件 .. 它做的事儿就是显示一个 hello ~ ninghao.net ,后面带个文本框 ..

再打开 entry.js .. 再改造一下它里面的东西 .. 先是导入 React ,ReactDOM ,还有 Name 这个组件 .. 然后用 ReactDOM 的 render 方法,把 Name 这个组件放到页面上的 id 是 app 的这个元素里面显示 ...

现在我们就基本上准备好了需要的东西 .. 下面可以去运行一下 webpack-dev-server .. 如果你嫌这个命令太长了,我们可以这样改造一下 .. 打开 package.json .. npm 的配置文件 .. 在它的 scripts 里面,添加一个命令 .. 比如 watch .. 它的值就是要执行的命令 .. webpack-dev-server --inline --hot ..

"watch": "webpack-dev-server --inline --hot"

保存 .. 回到命令行 .. 现在我们可以执行一下

 npm run watch

 .. 运行 scripts 里面的那个 watch 命令 ..

在浏览器上打开创建的这个开发服务器 .. localhost:8080 .. 页面上会显示在 name.js 里面创建的那个组件的内容 ..

打开浏览器的控制台 .. 下面我们可以再去试一下模块的热替换功能 .. 在这个页面上的文本框里输入点内容 .. 然后打开 name.js 修改一下要显示的文字 .. 保存 ..

在页面上会显示修改之后的结果 .. 而且并没有刷新整个页面,只是替换了有变化的地方 ...

来自 https://ninghao.net/video/3453#info

普通分类: