webpack third
css-loader残留的疑问
- 打包后的文件通过css-loader和style-loader后打包的文件确实有了明显变化,但是为什么css文件是被解压到了打包后的js文件中呢?
这个是style-loader的作用,将css代码转换为了js的字符串,然后在运行的时候将css通过style标签插入到head中。简单验证可以随便创建一个index.html然后通过script标签引入打包后的文件,打开创建的html。通过F12查看就可以发现如下图所示:
缺点:导致JavaScript的文件过大,会影响加载网页的时间。文件没有分离,糅杂在了一起。 - 解决办法–引入plugin
首先简单介绍下webpack的plugin是什么。plugin主要用来扩展webpack的功能,构建流程中注入钩子函数,增加webpack的灵活性。
引入主角
npm i -D extract-text-webpack-plugin
吐血,在这里卡住了下,果然不多看看就落伍了。请看截图:
意思这里的插件将被另外一个名为mini-css-extract-plugin取代
mini-css-extract-plugin
插件详细使用地址
将第一个插件删除
npm uninstall extract-text-webpack-plugin
安装适合webpack5的插件:
npm install --save-dev mini-css-extract-plugin
配置webpack.config.json如下:
const path = require('path');
// const ExtractText = require('extract-text-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const devMode = process.env.NODE_ENV !== 'production';
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
],
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? '[name].css' : '[name].[contenthash].css',
chunkFilename: devMode ? '[id].css' : '[id].[contenthash].css',
})
]
};
这个先不管devMode 这个属性,主要是用来判断环境的,开发还是生产的环境。
‘[name].css’ : ‘[name].[contenthash].css’,这个name表示文件名,因为是在mian.js使用的import引入,所以文件是安装依赖的js文件获取的名字,这里是main.css。contenthash是用来防止缓存的(缓存让你摸不清头脑,为什么不生效呢),根据内容生成,可以在后面使用[contenthash:8]表示八位的hash,内容改变才改变,存在一些细节差异,后面再进行补充。
执行打包命令:
npm run build
生成文件如下:
实现了抽离,但是我们的html没有引入,可手动引入。并且html没有经过webpack进行打包,接下来让html也被例如打包的进程。
html打包
安装插件 npm install --save-dev html-webpack-plugin
配置webpack.config.json
const path = require('path');
// const ExtractText = require('extract-text-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const devMode = process.env.NODE_ENV !== 'production';
module.exports = {
entry: './src/index.js',
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
},
module: {
rules: [
{
test: /\.css$/i,
use: [MiniCssExtractPlugin.loader, 'css-loader']
},
],
},
plugins: [
new MiniCssExtractPlugin({
// Options similar to the same options in webpackOptions.output
// both options are optional
filename: devMode ? '[name].css' : '[name].[contenthash].css',
chunkFilename: devMode ? '[id].css' : '[id].[contenthash].css',
}),
new HtmlWebpackPlugin({
filename: '[name].html'
}),
]
};
这样直接打包会默认生成一个main.html,但是这个html并不是你自己指定的,虽然引入了main.js和main.css,关键是没有自己的html结构,内容。
- 指定自己的html
src文件夹创建一个index.html,写点内容判断是否是自己的。
配置中通过属性template: './src/index.html'
来指定打包的文件。
执行打包,打包后文件是被压缩了的(明显少了空格)。
运行打包后的html明显是可观察出Js,css都生效了。
更多配置
minify:{
minimize:false, // 是否为最小
removeAttrbuteQuotes:true, // 是否去除引号
removeComments:true, // 是否去掉注释
collapseWhitespace:false, // 是否去掉空格
minifyCss:true, // 是否压缩css
removeEmptyElements:false, // 是否清理内容为空的元素
},
查看下dist文件夹,发现老的文件依然存在,这个会成为一个很大的问题,没有的文件也在打包文件中,因此我们需要删除。手动删除虽然也是个办法,但是程序员得做点想程序员的事。
output: {
filename: 'main.js',
path: path.resolve(__dirname, 'dist'),
clean: true,
},
这样就可以直接清除dist目录后再进行打包了。跟记忆中的方式不太一样,是因为它是webpack5啊,在webpack4中需要引入一个插件:clean-webpack-plugin
,引入后在plugins中new一下就好了。