开发也有一段时间了,接触的东西越多,发现需要学习的内容也就越多,为了以后更好的工作(加薪),下定苦心学习前端神器(webpack)。下面,走起!!!
版本说明:
- webpack v5.37.1
- node v12.13.1
一、入门
1.1初始化项目
新建一个目录(我这里建的事my-webpack
,之后也是用这个目录)
mkdir my-webpack
cd my-webpack
npm init
// 或者
mkdir my-webpack && cd my-webpack && npm init
复制代码
因webpack是需要node支持的,因此需要安装 webpack
、webpack-cli
包。
npm i -D webpack webpack-cli
复制代码
说明:-D 为 –save-dev 的缩写,-S 为 –save 的缩写
新建一个 src 目录,该目录下新建 main.js 文件并输入测试代码
console.log("webapck学习")
复制代码
配置 package.json 文件
"scripts": {
"build": "webpack ./src/main.js"
}
复制代码
新建 webpack.config.js 文件,并设置 mode 模式(可忽略,后期会在 build/ 目录下)
const isDev = false
module.exports = {
mode: isDev ? 'development' : 'production'
}
复制代码
运行
npm run build
复制代码
此时,生成了 dist/main.js 文件,说明打包成功了。
1.2 配置自己的打包命令
上面我们使用的都是webpack默认的配置,下面来实现自己的配置。
首先新建 build 文件,然后新建 webpack.config.js 文件, 写入以下配置代码:
const path = require('path')
const isDev = false
module.exports = {
mode: isDev ? 'development' : 'production', // 模式
entry: path.resolve(__dirname, '../src/main.js'), // 入口
output: {
path: path.resolve(__dirname, '../dist'), // 打包后目录
filename: 'build.js'
}
}
复制代码
更改 package.json 打包文件
"scripts": {
"build": "webpack --config build/webpack.config.js"
}
复制代码
然后执行 npm run build
就可以生成打包后的文件,其中 dist/build.js
文件就是主文件。
1.3 配置html模版
在实际开发中,或者vue开发者会发现打包之后生成的js文件每次都不一样,打包配置名称是通过哈希值来命名的
我们又不能每次都去更改html的引入,因此需要引入一个插件
npm i -D html-webpack-plugin
复制代码
配置打包文件
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const isDev = true
module.exports = {
mode: isDev ? 'development' : 'production', // 模式
entry: path.resolve(__dirname, '../src/main.js'), // 入口
output: {
path: path.resolve(__dirname, '../dist'), // 打包后目录
filename: '[name].[hash:8].js'
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../public/index.html')
})
]
}
复制代码
在根目录下新建 public/idnex.html 目录和文件,代码实现如图所示:
然后执行打包命令,就可以生成打包文件了,可以看出js已经引入了
1.3.1 多文件入口
有的时候我们会遇到前端入口和管理端入口分别是两个文件,这个时候可以使用 html-webpack-plugin
来实现多入口文件打包
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const isDev = true
module.exports = {
mode: isDev ? 'development' : 'production', // 模式
entry: {
main: path.resolve(__dirname, '../src/main.js'),
admin: path.resolve(__dirname, '../src/admin.js'),
},
output: {
path: path.resolve(__dirname, '../dist'), // 打包后目录
filename: '[name].[hash:8].js'
},
plugins: [
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../public/index.html'),
filename: 'index.html',
chunks: ['main'] // 与入口文件对应的模块名
}),
new HtmlWebpackPlugin({
template: path.resolve(__dirname, '../public/admin.html'),
filename: 'admin.html',
chunks: ['admin'] // 与入口文件对应的模块名
})
]
}
复制代码
执行npm run build 会生成以下目录
1.3.2 清理缓存
我们在多次使用 npm run build
打包之后,会发现dist文件中会存在过期的缓存文件,这个时候手动清除会比较困难和繁琐。因此,推荐一个打包之前清除缓存的插件 clean-webpack-plugin
。
const {
CleanWebpackPlugin
} = require('clean-webpack-plugin')
module.exports = {
// ...
plugins: [new CleanWebpackPlugin()]
}
复制代码
1.4 引入css
js 是我们的入口文件,因此在main.js 中引入css
// src/main.js
import "./assets/index.css"
import "./assets/style.less"
import "./assets/style.scss"
console.log('webpack学习-main')
复制代码
同时也需要插件 style-loader
、 css-loader
来解析css文件
npm i -D style-loader css-loader
复制代码
如果你是使用 less
、scss
来构建样式
npm i -D less less-loader
npm i -D node-sass sass-loader
复制代码
配置文件如下:
// webpack.config.js
module.exports = {
// ...
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader'] // 从右向左解析原则
}, {
test: /\.less$/,
use: ['style-loader', 'css-loader', 'less-loader'] // 从右向左解析原则
}, {
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'] // 从右向左解析原则
}]
},
}
复制代码
打包后打开 html 查看元素如下:
1.4.1 为css添加浏览器前缀(浏览器兼容处理)
浏览器的兼容问题可以说是让人头疼的一件事情,而使用 postcss-loader
、autoprefixer
loader之后,这些问题就不需要我们再去考虑啦。
npm i -D postcss-loader autoprefixer
复制代码
在配置中引入:
// webpack.config.js
module.exports = {
// ...
module:{
rules:[
{
test:/\.less$/,
use:['style-loader','css-loader','postcss-loader','less-loader']
}
]
}
}
复制代码
接下来,我们还需要引入 autoprefixer
来使其生效,这里有两种方法:
1.在根目录下新建 postcss.config.js
文件,并写入以下内容:
module.exports = {
plugins: [require('autoprefixer')]
}
复制代码
2.在 webpack.config.js 文件中配置
// webpack.config.js
module.exports = {
// ...
module:{
rules:[{
test:/\.less$/,
use:['style-loader','css-loader',{
loader:'postcss-loader',
options:{
plugins:[require('autoprefixer')]
}
},'less-loader']
}]
}
}
复制代码
运行打包之后发现,style 样式已经全部加载到了 html 页面中,我们发现如果样式比较多的话,页面会显得非常杂乱。因此,我们需要将 css 样式进行拆分。
1.4.2 拆分css
我们使用 mini-css-extract-plugin
来实现 css 拆分
npm i -D mini-css-extract-plugin
复制代码
说明:webpack4.0之前我们使用
extract-text-webpack-plugin
插件, webpack4.0之后我们使用mini-css-extract-plugin
插件
在配置中使用
// webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
// 'style-loader', // 此处需要删除,否则会报错
'css-loader',
],
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[hash].css",
chunkFilename: "[id].css",
})
]
}
复制代码
效果如下:
1.4.3 拆分多个css(webpack5.0忽略)
我们上面介绍了 mini-css-extract-plugin
的使用,但是该插件目前只能生成一个文件,想要实现拆分成多个css文件,我们需要引入 extract-text-webpack-plugin@next
插件。
需要说明的是,
extract-text-webpack-plugin@next
只能在webpack5.0以下使用。
安装插件
npm i -D extract-text-webpack-plugin@next
复制代码
配置文件
// webpack.config.js
const path = require('path');
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin')
let indexLess = new ExtractTextWebpackPlugin('index.less');
let indexCss = new ExtractTextWebpackPlugin('index.css');
module.exports = {
// ...
module:{
rules:[
{
test:/\.css$/,
use: indexCss.extract({
use: ['css-loader']
})
},
{
test:/\.less$/,
use: indexLess.extract({
use: ['css-loader','less-loader']
})
}
]
},
plugins:[
indexLess,
indexCss
]
}
复制代码
1.5 打包字体、图片、媒体等文件
上面我们将样式进行了打包处理,同时我们还需要将字体、图片、媒体等文件也进行打包处理,这时候我们用到 file-loader
插件,将文件输出到对应的目录中。
说到 file-loader
,我们还配合一个伴生插件 url-loader
来使用,如更文件小于限制的大小,返回base64编码,否则将文件移动到输出的目录下。
安装插件
npm i -D file-loader url-loader
复制代码
配置文件如下:
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
// 图片文件
{
test: /\.(jpe?g | png | gif)/i,
use: [{
loader: 'url-loader',
options: {
limit: 10240,
fallback: {
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
}
}
}]
},
// 媒体文件
{
test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/,
use: [{
loader: 'url-loader',
options: {
limit: 10240,
fallback: {
loader: 'file-loader',
options: {
name: 'media/[name].[hash:8].[ext]'
}
}
}
}]
},
// 字体文件
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/i,
use: [{
loader: 'url-loader',
options: {
limit: 10240,
fallback: {
loader: 'file-loader',
options: {
name: 'fonts/[name].[hash:8].[ext]'
}
}
}
}]
},
]
}
}
复制代码
1.6 用babel转义js文件
为了js能够兼容更多的环境,需要安装以下插件
npm i -D babel-loader @babel/preset-env @babel/core
复制代码
注意:babel-loader
和 @babel/core
版本的对应关系
babel-loader 8.x
对应@babel/core 7.x
babel-loader 7.x
对应@babel/core 6.x
配置文件如下:
// webpack.config.js
module.exports = {
// ...
module:{
rules:[
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env']
}
},
exclude:/node_modules/
},
]
}
}
复制代码
babel-loader
是只能将 ES6/7/8 转化成 ES5 语法,但是对于新的 API 是不做转换的(promise、Generator、Set、Maps、Proxy等)。因此,我们需要使用 @babel/polyfill
插件来解决这个问题。
npm i -D @babel/polyfill
复制代码
配置文件如下:
// webpack.config.js
const path = require('path')
module.exports = {
entry: ["@babel/polyfill",path.resolve(__dirname,'../src/index.js')],
}
复制代码
以上,我们将 webpack 的基础用法过了一遍,但是想要熟悉运用到实际开发中,还需要进行实战。下面让我们一起摆脱脚手架尝试自己搭建一个vue开发环境。
常用包整理
webpack
webpack工具webpack-cli
webpack脚手架html-webpack-plugin
将打包生成的 js 动态引入到 html 中,同时也可以实现多文件入口clean-webpack-plugin
每次打包之前清除 dist 下的缓存文件style-loader
、css-loader
解析css文件less
、less-loader
将 .less 结尾的文件解析成 css 文件node-sass
、sass-loader
将 .scss 结尾的文件解析成 css 文件postcss-loader
、autoprefixer
给css样式添加前缀(浏览器兼容性处理)mini-css-extract-plugin
将样式拆分成一个文件,webpack5.0 官方推荐使用extract-text-webpack-plugin
将样式拆分成一个或多个文件,只支持webpack4.0及一下版本file-loader
将文件输出到打包文件中url-loader
将文件输出到打包文件中,如更文件小于限制的大小,返回base64编码,否则将文件移动到输出的目录下。babel-loader
、@babel/preset-env
、@babel/core
、@babel/polyfill
转义js文件,兼容更多的环境
说明
该篇内容是笔者学习 黄小虫-2020年了,再不会webpack敲得代码就不香了(近万字实战) 大神写的关于 webpack 从入门到项目应用的学习记录。内容文本有摘抄,但全部代码笔者都已实现,在此记录,供更多人学习以及后期笔者回顾,谢谢您的阅读。
参考文献: