webpack 用于编译 JavaScript 模块。安装完成,就可以通过 webpack 的 CLI或 API与其配合交互。 动态打包(dynamically bundle)所有依赖项,创建所谓的依赖图(dependency graph)。每个模块都明确表述它自身的依赖,避免打包未使用的模块。还可以通过 loader 引入任何其他类型的文件。用来构建网站或 web 应用程序中的所有非 JavaScript 内容。
基本安装
首先创建一个目录,初始化 npm,然后在本地安装webpack
, webpack-cli
(此工具用于在命令行中运行 webpack):
mkdir learn_webpack && cd learn_webpack
npm init -y
npm install webpack webpack-cli --save-dev
ES2015 中的 import 和 export 语句已经被标准化。虽然大多数浏览器还无法支持它们,但是 webpack 能够提供开箱即用的支持。事实上,webpack 在幕后会将代码“转译”,以便旧版本浏览器可以执行。webpack 不会更改代码中除 import 和 export 语句以外的部分。如果使用其它 ES2015 特性,需要在 webpack 的 loader 系统中使用了一个类似 Babel 转译器。
配置文件
在 webpack 4 中,可以无须任何配置使用,然而大多数项目会需要很复杂的设置,所以webpack 仍然要支持配置文件。这比在终端(terminal)中手动输入大量命令要高效的多,创建一个配置文件: webpack.config.js
执行
webpack --config webpack.config.js
如果
webpack.config.js
存在,则webpack
命令将默认选择使用它。这里使用--config
选项只是想表明,可以传递任何名称的配置文件。适用于拆分成多个文件的复杂配置。
管理资源
- 加载CSS:从 JavaScript 模块中
import
一个 CSS 文件,需要在配置中安装并添加style-loader
和css-loader
npm install --save-dev style-loader css-loader
- 加载图片:
npm install --save-dev file-loader
- 加载数据:默认是支持JSON文件的(
import Data from './data.json'
),要导入导CSV 及 XML,需要安装:npm install --save-dev csv-loader xml-loader
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: ['file-loader']
}, {
test: /\.(csv|tsv)$/,
use: ['csv-loader']
},
{
test: /\.xml$/,
use: ['xml-loader']
}
]
}
};
管理输出
- 设定
html-webpack-plugin
:该插件将生成一个 HTML5 文件,所有的 bundle 会自动添加到 html 中; - 设定
clean-webpack-plugin
:清理/dist
文件夹,监听文件改变重新生成,未改变文件不会被清理; - 设定
webpack-manifest-plugin
(可选): 能够对「模块映射到输出 bundle 的过程」保持追踪。可以将数据提取到一个 json 文件中;说白了就是生成一个manifest.json 默认文件名, 是一个文件清单, 内容是打包前文件对应打包后的文件名。
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const { WebpackManifestPlugin } = require('webpack-manifest-plugin');
module.exports = {
plugins: [
new CleanWebpackPlugin({
cleanStaleWebpackAssets: false
}),
new HtmlWebpackPlugin({
title: '文档标题'
}),
new WebpackManifestPlugin(),
],
};
构建一个开发环境
使用 source map
当 webpack 打包源代码时,会很难追踪到错误和警告在源代码中的原始位置。将多个源文件打包到一个bundle.js
中,其中一个源文件包含一个错误,那么堆栈跟踪就会简单地指向到 bundle.js
。这通常并没有太多帮助,开发人员需要准确地知道错误来自于哪个源文件。
为了更容易追踪错误和警告,JavaScript 提供了 source map
功能,将编译后的代码映射回原始源代码。source map 会明确指出错误来自于哪个源文件及确切位置。
module.exports = {
// ...
devtool: 'inline-source-map', // 避免在生产中使用 inline-***, 会增加 bundle 大小,并降低整体性能。
};
选择一个开发工具
每次要编译代码时,手动运行 npm run build
很麻烦。,webpack 中有几个不同的选项,可以实现代码发生变化后自动编译代码:
- 观察模式:webpack's Watch Mode
- webpack-dev-server
- webpack-dev-middleware
观察模式
可以指示 webpack watch 依赖图中的所有文件的更改。如果其中一个文件被更新,代码将被重新编译,不必手动运行整个构建。添加一个用于启动 webpack 的观察模式的 npm script 脚本:package.json
"scripts": {
"watch": "webpack --watch",
},
在命令行中运行 npm run watch
,会看到 webpack 编译代码,却不会退出命令行,因为 script 脚本还在观察文件。当修改一个文件并保存后,可以看到 webpack 自动重新编译修改后的模块!唯一的缺点
: 需要刷新浏览器才能看到修改后的实际效果,而使用 webpack-dev-server
,可以实现自动刷新浏览器。
webpack-dev-server
webpack-dev-server
提供了一个简单的 web 服务器,并且能够实时重新加载(live reloading)。npm install --save-dev webpack-dev-server
webpack.config.js
module.exports = {
// 在 localhost:8080 下建立服务,将 dist 目录下的文件,作为可访问文件。
devServer: {
contentBase: './dist' // 开发服务器(dev server),查找文件位置
},
};
package.json
"scripts": {
"start": "webpack-dev-server --open",
},
在命令行中运行 npm start
,会看到浏览器自动加载页面。修改和保存任意源文件,web 服务器就会自动重新加载编译后的代码。
webpack-dev-middleware
webpack-dev-middleware
是一个容器(wrapper),可以把 webpack 处理后的文件传递给一个服务器(server)。 webpack-dev-server
内部使用了它,同时也可以作为一个单独的包来使用。
webpack-dev-middleware 配合 express server 使用:npm install --save-dev express webpack-dev-middleware
webpack.config.js
module.exports = {
// ...
output: {
// ...
publicPath: '/' // 会在服务器脚本用到,以确保文件资源能够在 http://localhost:3000 下正确访问
}
};
server.js
const express = require('express');
const webpack = require('webpack');
const webpackDevMiddleware = require('webpack-dev-middleware');
const app = express();
const config = require('./webpack.config.js');
const compiler = webpack(config);
// Tell express to use the webpack-dev-middleware and use the webpack.config.js
// configuration file as a base.
app.use(webpackDevMiddleware(compiler, {
publicPath: config.output.publicPath
}));
// Serve the files on port 3000.
app.listen(3000, function () {
console.log('Example app listening on port 3000!\n');
});
package.json
"scripts": {
"server": "node server.js",
},
在命令行中运行 npm run server
,打开浏览器 http://localhost:3000
,webpack 应用程序已经运行。