Skip to main content

webpack plugin 的基本使用

这节介绍了 webpack 一些常用的 plugins 的使用

我的总结篇的第一节什么是 webpack中提到了 index.html 是需要我们手动移动到打包后的 dist 目录下的,那么是否可以把这项工作交给程序来实现呢。🤔

这个时候 plugins 就派上了用场。

html-webpack-plugin

The HtmlWebpackPlugin simplifies creation of HTML files to serve your webpack bundles. This is especially useful for webpack bundles that include a hash in the filename which changes every compilation. You can either let the plugin generate an HTML file for you, supply your own template using lodash templates, or use your own loader.

官网介绍到,它可以帮我们自动创造 HTML 文件,并且还可以使用自定义的 HTML 模板。

直接看例子:

安装插件
npm i html-webpack-plugin -D
项目目录
webpacktest
├── package-lock.json
├── package.json
├── src
│ └── index.js
└── webpack.config.js
var root = document.getElementById('root');

root.innerHTML = '<div>Hello Webpack</div>';

npm run build进行打包看下结果

webpacktest
├── dist
│ ├── bundle.js
│ └── index.html
├── package-lock.json
├── package.json
├── src
│ └── index.js
└── webpack.config.js

HtmlWebpackPlugin 插件自动为我们在dist目录下生成了 index.html,但是...浏览器打开 index.html 一看什么都没有。这是咋回事,来看一看生成的 index.html 文件发现了问题

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Webpack App</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>

生成的文件中是没有#root节点的,那怎么办?我们还需要配置一下 HtmlWebpackPlugin,前面官网的介绍中也提到了

You can either let the plugin generate an HTML file for you, supply your own template using lodash templates, or use your own loader

我们需要自己提供一个 HTML 模板,于是在 src 目录下创建一个 index.html 作为 HtmlWebpackPlugin 打包的模板

src/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>html template</title>
</head>
<body>
<div id="root"></div>
</body>
</html>

再打包一次看一下 dist 目录下生成的 index.html 文件和我们定义的 html 模板是一样的了。

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>html template</title>
</head>
<body>
<div id="root"></div>
<script src="bundle.js"></script>
</body>
</html>

打开浏览器发现 Hello Webpack 也正确显示出来了。🎉

clean-webpack-plugin

https://www.npmjs.com/package/clean-webpack-plugin

它的作用就是在每次打包前会将 webpack 中配置的out.path(dist 目录)清空

npm i clean-webpack-plugin -D

为了验证是否清空了 dist 目录,我们先在 dist 目录下自己创建一个文件 my.js

dist
├── bundle.js
├── index.html
└── my.js
webpack.config.js
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
mode: 'development', // 默认为production
entry: {
main: './src/index.js' // 打包入口文件
},
output: {
// 输出文件配置
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin()
]
};

npm run build打包

dist
├── bundle.js
└── index.html

我们发现之前创建的 my.js 文件已经被 CleanWebpackPlugin 给清除了。

多入口文件

有时我们的打包入口文件有多个,这时候就要通过设置 entry 来完成打包。并通过[name]占位符来设置打包出来的文件的名称。

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');

module.exports = {
mode: 'development', // 默认为production
entry: {
main: './src/index.js', // 打包入口文件
enrty: './src/entry.js'
},
output: {
// 输出文件配置
filename: '[name].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin()
]
};

npm run build打包结果

dist
├── enrty.js
├── index.html
└── main.js

看一看 index.html

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>html template</title>
</head>
<body>
<div id="root"></div>
<script src="main.js"></script>
<script src="enrty.js"></script>
</body>
</html>

可以看到 HtmlWebpackPlugin 帮我们把main.jsentry.j2 个文件都自动引入到 html 文件当中了。

在实际业务场景中,为了优化服务器性能,我们会将打包好的 dist 目录中的一部分文件丢到 cdn 中来加快访问速度。这时候我们就要将 cdn 的地址手动复制到打包后的 html 文件中了,不过我们可以通过设置 output 的 publicPath 来完成。

output: {
// 输出文件配置
filename: '[name].js',
publicPath: 'https://cdn.example.com/assets',
path: path.resolve(__dirname, 'dist'),
},

打包后的效果

<script src="https://cdn.example.com/assets/main.js"></script>
<script src="https://cdn.example.com/assets/enrty.js"></script>

SourceMap

sourcemap 是什么,我们修改一下 index.js 文件内容并且在 webpack 配置中关闭 sourcemap(devtool: 'none')

var root = document.getElementById('root');

errfun();

root.innerHTML = '<div>Hello Webpack</div>';

index.js 中使用了一个不存在的函数 errfun(),打包运行一下是会报错的。

image-20200517134620514

这个时候我们想要调试代码,但是它这里提示的错误行是打包后的 main.js 所在的位置,而打包后的文件可读性几乎为 0,想要从中排查错误将变得很困难。

现在我们配置 sourcemap 看看。

devtool: 'source-map',

image-20200517135446504

通过开启 source-map 我们就能定位到错误是出现在我们 index.js 的第三行了。

warning

配置不同 sourceMap 会不同程度上增加应用的打包时间或消耗性能

官网提供了多种 sourceMap 配置,不同 sourceMap 打包消耗时间不同,详情

总结

sourcemap 其实就是 main.js 和 index.js 之间的一种映射关系,在代码存在错误时,它能根据映射关系找到 index.js 中的错误所在处,有利于我们 debug 代码。