webpack-1回顾
在webpack-1中,我们做了以下事情:
- 使用了webpack打包了js文件
- 使用html插件打包了html
- 使用css插件打包css
- 使用
css loader打包css - 使用webpack server搭建开发环境
- 部署开发环境与生产环境
- 配置package.json文件
我们做一下简单的总结:
1、webpack天生支持js文件,能识别js文件快速打包
2、使用html插件会自动生成一个html文件,或者使用模板文件来生成以源代码为基础的html文件。所以我们只需要提供0-1的html文件就可以webpack打包
3、使用css loader模式来打包css,最终会以js文件的形式新增style标签到html文件中
4、使用css插件会生成css文件的形式link到html中
5、我们可以通过浏览器缓存的特性来搭建生产环境,并且让webpack帮我们hash文件名
6、webpack server提供我们开发支持,虽然官方文档中说会以dist目录里的文件做server,但是实际上删除生成的dist目录也不影响效果,说明webpack内部隐式做了处理,并不是以生成的dist目录为准。所以我们可以通过这个功能来搭建开发环境
7、webpack的配置真的是一件麻烦的事情啊~
loader与plugin的区别
1、loader是加载器,plugin是插件
2、loader用来load一个文件,以css loade为例,它能够(通过js的方式)将css load成style,所以我们需要在配置中的use项写style loader跟css loader
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ] //写了两个
}
]
}
}
而plugin是用来增强webpack功能的,它能够生成插件支持的格式文件,所以我们可以发现,只要我们import了css,最终会生成一份css文件,并且让你的index.html自动link到它。html webpack plugin则会生成一份html文件
打包scss文件
按照上面的套路,我们已经知道了,我们可以使用loader或者plugin来打包scss文件,首先是安装
yarn add sass-loader dart-sass --dev
安装sass-loader跟dart-sass
配置
module: {
rules: [{
test: /\.s[ac]ss$/i,
use: [
'style-loader',
'css-loader',
{
loader: 'sass-loader',
options: {
implementation: require('dart-sass'),
},
},
],
}]
}
打包less文件
安装
yarn add less less-loader --dev
配置
{
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'] // compiles Less to CSS
}
打包stylus
安装
yarn add stylus stylus-loader --dev
配置
module.exports = {
module: {
rules: [
{
test: /\.styl/,
use: ['style-loader', 'css-loader', 'stylus-loader']
},
],
},
};
打包图片
安装
yarn add file-loader --dev
配置
module.exports = {
module: {
rules: [
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'file-loader',
},
],
},
],
},
};
使用
import png from './file/1.png' //引入后可以当成变量使用
document.querySelector('.app').innerHTML = `<img src=${png}></img>`
懒加载
懒加载或者按需加载,是一种很好的优化网页或应用的方式。
如果说我们的js文件体积很大,或者一开始就不需要加载,那么当用户打开时,我们可以设置某个事件情况下才加载js文件。
以click事件为例,我们来模拟一下懒加载
步骤
- 准备一个懒加载
- 新建一个js文件,内容如下:
function fn() {
console.log('懒加载')
}
export default fn
- 在
index.js文件中设置button的点击事件
document.querySelector('button').onclick = () => {
const p = import('./lazy.js') //此时p是promise对象
console.log(p) //打出来看看
p.then((module) => { //成功后promiseResult会返回一个module,通过内部的default属性可以获得export出来的函数
module.default()
}, () => {
console.log('失败后的代码')
})
}
通过import函数后的promise返回结果,Module
结论
webpack通过import函数返回一个promise,成功后这个promise会带着Module结果,我们只需要在then里做处理即可实现懒加载,参数就是Module
代码分离
我在提交github前yarn build了一下,发现我tm没有给production环境配webpack的loader,这就很烦了,我还得再写一遍到production环境的config,js里面吗?
然后我大概花了三个小时,找方法一小时,抄文档半小时,剩下一个半小时在看为什么不行。
终于让我试完了,我将在这里写下我踩的坑
方法主要是需要建立common文件,然后使用插件让他们合并关联
安装插件
yarn add webpack-merge --dev
这个插件可以帮助我们关联config文件
准备config文件
准备三份config文件,分别是common(放公共样式)、dev(开发环境)、prod(生产环境)
我的命名
|- webpack.common.js
|- webpack.dev.js
|- webpack.prod.js
config文件设置
common.js中丢入公共的打包配置即可。以我的为例
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/index.js',
output: {
filename: '[name].[contenthash].js',
path: path.resolve(__dirname, 'dist')
},
plugins: [
new HtmlWebpackPlugin({
title: 'qiuyanxi',
template: 'src/index.html'
}),
];
common的里面丢一些公共配置,例如less啊,png啊之类的配置
dev.js里面丢开发者环境,以我的为例
const {
merge
} = require('webpack-merge');
const common = require('./webpack.common.js');
//--------上面这两句一定要写
//--------日常踩坑,这里要写merge(common,{})
module.exports = merge(common, {
mode: `development`,
devtool: 'inline-source-map',
devServer: {
contentBase: './dist',
},
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
}
})
请注意我的注释
prod里面丢生产环境,以我的为例
const {
merge
} = require('webpack-merge');
const common = require('./webpack.common.js');
//---------------------上面这两句一定要写
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
//---------日常踩坑,这里要写merge(common,{})
module.exports = merge(common, {
mode: `production`,
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css',
ignoreOrder: false,
}),
],
module: {
rules: [{
test: /\.css$/,
use: [{
loader: MiniCssExtractPlugin.loader,
options: {
publicPath: '../',
// hmr: process.env.NODE_ENV === 'development',
},
},
'css-loader',
],
}, ],
},
});
说明
上面的代码中,我只是把css loader跟MINI-css plugin做了区分,其他都基本在公共文件common.js中
配置package.json
"scripts": {
"build": "rm -rf dist && npx webpack --config webpack.prod.js",
"start": "webpack-dev-server --open --config webpack.dev.js"
},
最后吐槽
webpack真香,配置真烦,官方文档学习成本真的高,害我今天坐一天了就搞这些玩意。
参考文档
代码分离:webpack.js.org/guides/prod…
懒加载:www.webpackjs.com/guides/lazy…