是用于现代JavaScript应用程序的静态模块捆绑器。 当webpack处理您的应用程序时,它会在内部构建一个依赖关系图,该图映射您项目所需的每个模块并生成一个或多个捆绑包。
起步 webpack 用于编译 JavaScript 模块。一旦完成安装,就可以通过 webpack 的 CLI 或 API 与其配合交互。
基本安装 创建一个目录,初始化 npm,然后 在本地安装 webpack,接着安装 webpack-cli(此工具用于在命令行中运行 webpack):
1 2 3 mkdir webpack-demo && cd webpack-demo npm init -y npm install webpack webpack-cli --save-dev
创建以下目录结构、文件和内容:
project
1 2 3 4 5 webpack-demo |- package.json + |- index.html + |- /src + |- index.js
src/index.js
1 2 3 4 5 6 7 function component ( ) { var element = document .createElement('div' ); element.innerHTML = _.join(['Hello' , 'webpack' ], ' ' ); return element; } document .body.appendChild(component());
index.html
1 2 3 4 5 6 7 8 9 10 <!doctype html > <html > <head > <title > 起步</title > <script src ="https://unpkg.com/lodash@4.16.6" > </script > </head > <body > <script src ="./src/index.js" > </script > </body > </html >
还需要调整 package.json 文件,以便确保我们安装包是私有的(private),并且移除 main 入口。这可以防止意外发布的代码。
package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 { "name" : "webpack-demo" , "version" : "1.0.0" , "description" : "" , + "private": true, - "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.0.1", "webpack-cli": "^2.0.9" }, "dependencies": {} }
在此示例中,<script>
标签之间存在隐式依赖关系。index.js 文件执行之前,还依赖于页面中引入的 lodash。之所以说是隐式的是因为 index.js 并未显式声明需要引入 lodash,只是假定推测已经存在一个全局变量 _。
使用这种方式去管理 JavaScript 项目会有一些问题:
无法立即体现,脚本的执行依赖于外部扩展库(external library)。 如果依赖不存在,或者引入顺序错误,应用程序将无法正常运行。 如果依赖被引入但是并没有使用,浏览器将被迫下载无用代码。 使用 webpack 来管理这些脚本。
创建一个 bundle 文件 首先,稍微调整下目录结构,将“源”代码(/src)从“分发”代码(/dist)中分离出来。“源”代码是用于书写和编辑的代码。“分发”代码是构建过程产生的代码最小化和优化后的“输出”目录,最终将在浏览器中加载:
project
1 2 3 4 5 6 7 webpack-demo |- package.json + |- /dist + |- index.html - |- index.html |- /src |- index.js
要在 index.js 中打包 lodash 依赖,需要在本地安装 library:
npm install --save lodash
在安装一个要打包到生产环境的安装包时,应该使用 npm install –save,如果在安装一个用于开发环境的安装包(例如,linter, 测试库等),应该使用 npm install –save-dev。请在 npm 文档 中查找更多信息。
现在,在脚本中 import lodash:
src/index.js
1 2 3 4 5 6 7 8 9 10 11 + import _ from 'lodash' ; + function component ( ) { var element = document .createElement('div' ); - + element.innerHTML = _.join(['Hello' , 'webpack' ], ' ' ); return element; } document .body.appendChild(component());
现在,由于通过打包来合成脚本,必须更新 index.html 文件。因为现在是通过 import 引入 lodash,所以将 lodash <script>
删除,然后修改另一个 <script>
标签来加载 bundle,而不是原始的 /src 文件:
dist/index.html
1 2 3 4 5 6 7 8 9 10 11 <!doctype html > <html > <head > <title > 起步</title > - <script src ="https://unpkg.com/lodash@4.16.6" > </script > </head > <body > - <script src ="./src/index.js" > </script > + <script src ="main.js" > </script > </body > </html >
在这个设置中,index.js 显式要求引入的 lodash 必须存在,然后将它绑定为 _(没有全局作用域污染)。通过声明模块所需的依赖,webpack 能够利用这些信息去构建依赖图,然后使用图生成一个优化过的,会以正确顺序执行的 bundle。
可以这样说,执行 npx webpack,会将脚本作为 入口起点 ,然后 输出 为 main.js。Node 8.2+ 版本提供的 npx 命令,可以运行在初始安装的 webpack 包(package)的 webpack 二进制文件(./node_modules/.bin/webpack):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 npx webpack Hash: dabab1bac2b940c1462b Version: webpack 4.0.1 Time: 3003ms Built at: 2018-2-26 22:42:11 Asset Size Chunks Chunk Names main.js 69.6 KiB 0 [emitted] main Entrypoint main = main.js [1] (webpack)/buildin/module.js 519 bytes {0} [built] [2] (webpack)/buildin/global.js 509 bytes {0} [built] [3] ./src/index.js 256 bytes {0} [built] + 1 hidden module WARNING in configuration(配置警告) The 'mode' option has not been set . Set 'mode' option to 'development' or 'production' to enable defaults for this environment.('mode' 选项还未设置。将 'mode' 选项设置为 'development' 或 'production' ,来启用环境默认值。)
输出可能会稍有不同,但是只要构建成功,那么就可以继续。并且不要担心,稍后就会解决。
在浏览器中打开 index.html,如果一切访问都正常,应该能看到以下文本:’Hello webpack’。
模块 ES2015 中的 import 和 export 语句已经被标准化。虽然大多数浏览器还无法支持它们,但是 webpack 却能够提供开箱即用般的支持。
事实上,webpack 在幕后会将代码“转译”,以便旧版本浏览器可以执行。如果检查 dist/bundle.js,可以看到 webpack 具体如何实现,这是独创精巧的设计!除了 import 和 export,webpack 还能够很好地支持多种其他模块语法,更多信息请查看模块 API。
注意,webpack 不会更改代码中除 import 和 export 语句以外的部分。如果使用其它 ES2015 特性,请确保在 webpack 的 loader 系统中使用了一个像是 Babel 或 Bublé 的转译器。
使用一个配置文件 在 webpack 4 中,可以无须任何配置使用,然而大多数项目会需要很复杂的设置,这就是为什么 webpack 仍然要支持 配置文件。这比在终端(terminal)中手动输入大量命令要高效的多,所以让创建一个取代以上使用 CLI 选项方式的配置文件:
project
1 2 3 4 5 6 7 webpack-demo |- package.json + |- webpack.config.js |- /dist |- index.html |- / src|- index.js
webpack.config.js
1 2 3 4 5 6 7 8 const path = require ('path' );module .exports = { entry: './src/index.js' , output: { filename: 'bundle.js' , path: path.resolve(__dirname, 'dist' ) } };
现在,通过新配置文件再次执行构建:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 npx webpack --config webpack.config.js Hash: dabab1bac2b940c1462b Version: webpack 4.0 .1 Time: 328 ms Built at: 2018 -2 -26 22 :47 :43 Asset Size Chunks Chunk Names bundle.js 69.6 KiB 0 [emitted] main Entrypoint main = bundle.js [1 ] (webpack)/buildin/module .js 519 bytes {0 } [built] [2 ] (webpack)/buildin/global.js 509 bytes {0 } [built] [3 ] ./src/index.js 256 bytes {0 } [built] + 1 hidden module WARNING in configuration(配置警告) The 'mode' option has not been set . Set 'mode' option to 'development' or 'production' to enable defaults for this environment.('mode' 选项还未设置。将 'mode' 选项设置为 'development' 或 'production',来启用环境默认值。)
注意,当在 windows 中通过调用路径去调用 webpack 时,必须使用反斜线()。例如 node_modules\.bin\webpack --config webpack.config.js。
如果 webpack.config.js 存在,则 webpack 命令将默认选择使用它。在这里使用 --config 选项只是表明,可以传递任何名称的配置文件。这对于需要拆分成多个文件的复杂配置是非常有用。
比起 CLI 这种简单直接的使用方式,配置文件具有更多的灵活性。可以通过配置方式指定 loader 规则(loader rules)、插件(plugins)、解析选项(resolve options),以及许多其他增强功能。了解更多详细信息,请查看配置文档。
NPM 脚本(NPM Scripts) 考虑到用 CLI 这种方式来运行本地的 webpack 不是特别方便,可以设置一个快捷方式。在 package.json 添加一个 npm 脚本(npm script):
package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 { "name" : "webpack-demo" , "version" : "1.0.0" , "description" : "" , "main" : "index.js" , "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" , + "build": "webpack" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "webpack": "^4.0.1", "webpack-cli": "^2.0.9", "lodash": "^4.17.5" } }
现在,可以使用 npm run build 命令,来替代之前使用的 npx 命令。注意,使用 npm 的 scripts,可以像使用 npx 那样通过模块名引用本地安装的 npm 包。这是大多数基于 npm 的项目遵循的标准,因为它允许所有贡献者使用同一组通用脚本(如果必要,每个 flag 都带有 –config 标志)。
现在运行以下命令,然后看看脚本别名是否正常运行:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 npm run build Hash: dabab1bac2b940c1462b Version: webpack 4.0.1 Time: 323ms Built at: 2018-2-26 22:50:25 Asset Size Chunks Chunk Names bundle.js 69.6 KiB 0 [emitted] main Entrypoint main = bundle.js [1] (webpack)/buildin/module.js 519 bytes {0} [built] [2] (webpack)/buildin/global.js 509 bytes {0} [built] [3] ./src/index.js 256 bytes {0} [built] + 1 hidden module WARNING in configuration(配置警告) The 'mode' option has not been set . Set 'mode' option to 'development' or 'production' to enable defaults for this environment.('mode' 选项还未设置。将 'mode' 选项设置为 'development' 或 'production' ,来启用环境默认值。)
通过向 npm run build 命令和参数之间添加两个中横线,可以将自定义参数传递给 webpack,例如:npm run build -- --colors。
结论 现在,已经实现了一个基本的构建过程,应该移至下一章节的 Asset Management 指南,以了解如何通过 webpack 来管理资源,例如图片、字体。此刻项目应该和如下类似:
project
1 2 3 4 5 6 7 8 9 webpack-demo |- package.json |- webpack.config.js |- /dist |- bundle.js |- index.html |- /src |- index.js |- /node_modules
如果使用的是 npm 5,可能还会在目录中看到一个 package-lock.json 文件。