Webpack 2 学习笔记
2017-07-14 #Coding #工程化

起步

https://doc.webpack-china.org/guides/getting-started/

管理资源

https://doc.webpack-china.org/guides/asset-management/

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

css分离引用

请注意,你也可以进行 CSS 分离,以便在生产环境中节省加载时间。最重要的是,现有的 loader 可以支持任何你可以想到的 CSS 处理器风格 - postcss, sass 和 less 等。

1
2
3
4
# 对于 webpack 2
npm install --save-dev extract-text-webpack-plugin
# 对于 webpack 1
npm install --save-dev extract-text-webpack-plugin@1.0.1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
const ExtractTextPlugin = require("extract-text-webpack-plugin");

module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin("styles.css"),
]}

它会将所有的入口 chunk(entry chunks)中引用的 *.css,移动到独立分离的 CSS 文件。因此,你的样式将不再内嵌到 JS bundle 中,而是会放到一个单独的 CSS 文件(即 styles.css)当中。 如果你的样式文件大小较大,这会做更快提前加载,因为 CSS bundle 会跟 JS bundle 并行加载。

https://doc.webpack-china.org/plugins/extract-text-webpack-plugin/

加载图片

1
npm install --save-dev file-loader

合乎逻辑下一步是,压缩和优化您的图像。查看image-webpack-loaderurl-loader,以了解更多关于如果增强加载处理图片功能。

加载字体

https://doc.webpack-china.org/guides/asset-management/#

加载数据

在使用 d3 等工具来实现某些数据可视化时,预加载数据会非常有用。我们可以不用再发送 ajax 请求,然后于运行时解析数据,而是在构建过程中将其提前载入并打包到模块中,以便浏览器加载模块后,可以立即从模块中解析数据。

管理输出

https://doc.webpack-china.org/guides/output-management/

多文件 bundle

dist/index.html

1
2
3
4
5
6
7
8
9
10
11
  <html>
<head>
- <title>Asset Management</title>
+ <title>Output Management</title>
+ <script src="./print.bundle.js"></script>
</head>
<body>
- <script src="./bundle.js"></script>
+ <script src="./app.bundle.js"></script>
</body>
</html>

调整配置,在 entry 添加 src/print.js 作为新的入口起点(print),然后修改 output,以便根据入口起点名称动态生成 bundle 名称:

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
  const path = require('path');

module.exports = {
entry: {
- index: './src/index.js',
+ app: './src/index.js',
+ print: './src/print.js'
},
output: {
- filename: 'bundle.js',
+ filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};

output 中 filename: ‘[name].bundle.js’ name为 entry 传输key名 [hash]可以增加hash值

设定 HtmlWebpackPlugin 设置html模板

1
npm install --save-dev html-webpack-plugin

https://doc.webpack-china.org/guides/output-management/#-htmlwebpackplugin

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
  const path = require('path');
+ const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
entry: {
app: './src/index.js',
vendor: ['lodash']
},
+ plugins: [
+ new HtmlWebpackPlugin({
+ title: 'Output Management'
+ })
+ ],
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};

虽然在 dist/ 文件夹我们已经有 index.html 这个文件,然而 HtmlWebpackPlugin 还是会默认生成 index.html 文件。这就是说,它会用新生成的 index.html 文件,把原来的文件替换。

公共依赖打包

vendor: [‘lodash’] 使用这种方式可以打包 依赖相关
使用 webpack.optimize.CommonsChunkPlugin 打包公共依赖

清理 /dist 文件夹

1
2
3
npm install clean-webpack-plugin --save-dev

const CleanWebpackPlugin = require('clean-webpack-plugin')

多模板入口

https://github.com/jantimon/html-webpack-plugin#generating-multiple-html-files

1
2
3
4
5
6
7
8
9
10
11
plugins: [
new CleanWebpackPlugin(["dist"]),
new HtmlWebpackPlugin({
filename: "index.html",
template: "src/index.html",
}),
new HtmlWebpackPlugin({
filename: "test.html",
template: "src/index.html",
}),
]

Manifest

你可能会感兴趣,webpack及其插件似乎“知道”应该哪些文件生成。答案是,通过 manifest,webpack 能够对「你的模块映射到输出 bundle 的过程」保持追踪。如果你对通过其他方式来管理 webpack 的输出更感兴趣,那么首先了解 manifest 是个好的开始。

通过使用 WebpackManifestPlugin,可以直接将数据提取到一个 json 文件,以供使用。
深入阅读 manifest的概念页面 ,以及通过缓存指南来弄清如何与长期缓存相关联。

代码分离

https://doc.webpack-china.org/guides/code-splitting/
Entry 参考 上面 多文件 bundle

防止重复 去掉重复引用 (重要) 示例中以 lodash为例

使用 CommonsChunkPlugin
明确打包第三方库 https://doc.webpack-china.org/plugins/commons-chunk-plugin/#-chunk

1
2
3
4
5
6
7
8
9
10
11
entry: {
vendor: ["jquery", "other-lib"],
app: "./entry"}new webpack.optimize.CommonsChunkPlugin({
name: "vendor",

// filename: "vendor.js"
// (给 chunk 一个不同的名字)

minChunks: Infinity,
// 随着 entrie chunk 越来越多,
// 这个配置保证没其它的模块会打包进 vendor chunk})

1
<script src="vendor.js" charset="utf-8"></script><script src="app.js" charset="utf-8"></script>

开发

webpack Watch Mode

1
webpack --progress --watch

在文件中做一点更改并且保存,会看到 webpack 正在重新编译。
观察模式对服务器没有作预设,所以需要自己提供。使用 serve 搭建一个简易的服务器。安装 npm install --save-dev serve,你可以在输出的文件目录下运行:

1
`npm bin`/serve

npm scripts 运行 serve 更方便,在package.json中创建一个 start 脚本:

1
2
3
4
...
"scripts": {
"start": "serve"}
...

npm start 来启动服务器。在每一次编译后,需要手动刷新你的浏览器来查看更改。

–single 选项对于提供单页应用服务非常有用。

webpack-dev-server

webpack-dev-server 提供了一个服务器和实时重载(live reloading)功能。
确定有一个index.html文件指向你的bundle。假设 output.filenamebunlde.js

1
<script src="/bundle.js"></script>

npm 安装 webpack-dev-server

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

然后启动

1
webpack-dev-server --open

如果控制台说无法找到该命令,尝试运行 node_modules/.bin/webpack-dev-server。正常情况下应该把该命令加在package.json中,例如:"scripts": {"start": "webpack-dev-server"}

更多信息参考:https://doc.webpack-china.org/guides/development/#webpack-dev-server

webpack-dev-middleware

webpack-dev-middleware 适用于基于链接的中间件环境(connect-based middleware stacks)。如果你已经有一个 Node.js 服务器或者你想要完全控制服务器,这个中间件将很实用。

这个中间件会导致 webpack 在内存中编译文件。当一个编译正在执行的时候,它会将对于文件的请求延迟,直到编译完成。

可以混合express 使用。

模块热替换

模块热替换(Hot Module Replacement 或 HMR)是 webpack 提供的最有用的功能之一。它允许在运行时更新各种模块,而无需进行完全刷新。本页面重点介绍实现,而概念页面提供了更多关于它的工作原理以及为什么它有用的细节。
https://doc.webpack-china.org/guides/hot-module-replacement/

类似有 vue-loader

生产环境构建

https://doc.webpack-china.org/guides/production/

  • 自动方式
  • JS文件压缩
  • Source Maps
  • Node 环境变量
  • 手动方式
  • 简单途径
  • 高级途径

Shimming 打包 jquery 等

https://doc.webpack-china.org/guides/shimming/

webpack 作为模块打包工具可以支持 ES2015 模块,根据 CommonJS 或者 AMD 规范编写的模块。但是很多时候,当使用第三方 library 的时候,可以看出还期望有一些全局依赖,比如对于大家都知道 jquery 的 $。这可能也会创建一些需要被导出的全局变量。在此,会看到通过不同的方式去帮助 webpack 支持这些彼此割裂的模块。

开发 - Vagrant

https://doc.webpack-china.org/guides/development-vagrant/