一,最基础的环境
1,初始化环境
yarn init (npm init)
2,安装webpack webpack-cli
说明webpack-cli 在4.0版本已经脱离了webpack 需要单独按照,个人建议最好把按照包安装在项目环境里,这样可以确保整个项目用的版本一样
yarn add webpack
yarn add webpack-cli
3,在package.json 添加script
"scripts": { "build": "webpack --mode production" }
4,我们在项目目录下添加一个文件src/index.js
(这是webpack默认的入口文件)
5,执行命令
yarn run dev
6, webpack.config.js的基本内容
const path = require('path')
const UglifyPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
},
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader',
include: [path.resolve(__dirname, 'src')]
},
],
},
// 代码模块路径解析的配置
resolve: {
modules: [
"node_modules",
path.resolve(__dirname, 'src')
],
extensions: [".wasm", ".mjs", ".js", ".json", ".jsx"],
},
plugins: [
new UglifyPlugin(),
// 使用 uglifyjs-webpack-plugin 来压缩 JS 代码
// 如果你留意了我们一开始直接使用 webpack 构建的结果,你会发现默认已经使用了 JS 代码压缩的插件
// 这其实也是我们命令中的 --mode production 的效果,后续的小节会介绍 webpack 的 mode 参数
],
}
基本解析:
注意:loader 和plugins都需要单独安装, 安装到 devDependencies 因为这些插件都只是构建代码时候有用
二,常用plugins
1,UglifyPlugin
这个用来进行js代码压缩
yarn add uglifyjs-webpack-plugin --dev
2,html-webpack-plugin
这个用户把打包好的js文件动态插入到index.html 默认入口文件为根目录下index.html 出口文件默认为dist目录下index.tml
yarn add uglifyjs-webpack-plugin --dev
也允许自己定义
module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html', // 配置输出文件名和路径
template: 'assets/index.html', // 配置文件模板
}),
],
}
⚠️为什么需要这个插件?为什么要动态插入? 主要是因为我们进行打包 为了防止浏览器缓存,往往需要给打包出来到文件添加[hash]。 所以就需要动态插入
3,extract-text-webpack-plugin@next
如果只用 css-loader & style-loader来转换代码,css会编程js代码动态插入到html中 如果想把css单独成一个文件,就需要使用这个plugin
4,DefinePlugin
DefinePlugin 是 webpack 内置的插件,可以使用 webpack.DefinePlugin 直接获取。
这个插件用于创建一些在编译时可以配置的全局常量,这些常量的值我们可以在 webpack 的配置中去指定,例如:
5,copy-webpack-plugin
我们一般会把开发的所有源码和资源文件放在 src/ 目录下,构建的时候产出一个 build/ 目录,通常会直接拿 build 中的所有文件来发布。有些文件没经过 webpack 处理,但是我们希望它们也能出现在 build 目录下,这时就可以使用 CopyWebpackPlugin 来处理了。
一般开发时,会在根目录下static目录直接拷贝过去
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: 'static',
ignore: ['.*']
}
])
yarn add copy-webpack-plugin -D
6,ProvidePlugin
ProvidePlugin 也是一个 webpack 内置的插件,我们可以直接使用 webpack.ProvidePlugin 来获取。
该组件用于引用某些模块作为应用运行时的变量,从而不必每次都用 require 或者 import,其用法相对简单:
new webpack.ProvidePlugin({
identifier: 'module',
// ...
})
// 或者
new webpack.ProvidePlugin({
identifier: ['module', 'property'], // 即引用 module 下的 property,类似 import { property } from 'module'
// ...
})
在你的代码中,当 identifier 被当作未赋值的变量时,module 就会被自动加载了,而 identifier 这个变量即 module 对外暴露的内容。
注意,如果是 ES 的 default export,那么你需要指定模块的 default 属性:identifier: ['module', 'default'],。
7,IgnorePlugin
IgnorePlugin 和 ProvidePlugin 一样,也是一个 webpack 内置的插件,可以直接使用 webpack.IgnorePlugin 来获取。
这个插件用于忽略某些特定的模块,让 webpack 不把这些指定的模块打包进去。例如我们使用 moment.js,直接引用后,里边有大量的 i18n 的代码,导致最后打包出来的文件比较大,而实际场景并不需要这些 i18n 的代码,这时我们可以使用 IgnorePlugin 来忽略掉这些代码文件,配置如下
module.exports = {
// ...
plugins: [
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/)
]
}
8,optimize-css-assets-webpack-plugin
css 代码压缩
const optimizeCss = require('optimize-css-assets-webpack-plugin');
plugins: [
new optimizeCss()
]
yarn add optimize-css-assets-webpack-plugin -D
三,常用loaders
1,babel-loader
这个loader可以把es6 + 代码转换为es5到代码。因为浏览器对于es6的代码兼容不好,但是es6很多新语法对于我们开发工作提升很高。所以需要把 es6代码做转换。
yarn add babel-loader @babel/core --dev
2,css-loader & style-loader
css-loader 负责解析 CSS 代码,主要是为了处理 CSS 中的依赖,例如 @import 和 url() 等引用外部文件的声明; style-loader 会将 css-loader 解析的结果转变成 JS 代码,运行时动态插入 style 标签来让 CSS 代码生效。
{
test: /\.css/,
include: [
path.resolve(__dirname, 'src'),
],
use: [
'style-loader',
'css-loader',
],
}
注意:['style-loader','css-loader']这里的配置是有顺序的,但规则应用顺序是从右到左的。也就是先 css-loader,再style-loader
yarn add css-loader style-loader --dev
3,less-loader
css 预编译器
module.exports = {
// ...
module: {
rules: [
{
test: /\.less$/,
// 因为这个插件需要干涉模块转换的内容,所以需要使用它对应的 loader
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [
'css-loader',
'less-loader',
],
}),
},
],
},
// ...
}
yarn add less less-loader -D
4,file-loader & url-loader & image-webpack-loader
file-loader 可以用于处理图片文件
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {},
},
],
}
yarn add file-loader -D
简答地说,url-loader封装了file-loader。url-loader不依赖于file-loader,即使用url-loader时,只需要安装url-loader即可,不需要安装file-loader,因为url-loader内置了file-loader。
通过上面的介绍,我们可以看到,url-loader工作分两种情况:
1)文件大小小于limit参数,url-loader将会把文件转为DataURL;
2)文件大小大于limit,url-loader会调用file-loader进行处理,参数也会直接传给file-loader。因此我们只需要安装url-loader即可。
url-loader
{
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('img/[name].[hash:7].[ext]')
}
},
{
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
loader: 'url-loader',
query: {
limit: 10000,
name: utils.assetsPath('fonts/[name].[hash:7].[ext]')
}
}
yarn add url-loader -D
image-webpack-loader可以用来做图片压缩
{
loader: 'image-webpack-loader',
options: {
mozjpeg: { // 压缩 jpeg 的配置
progressive: true,
quality: 65
},
optipng: { // 使用 imagemin-optipng 压缩 png,enable: false 为关闭
enabled: false,
},
pngquant: { // 使用 imagemin-pngquant 压缩 png
quality: '65-90',
speed: 4
},
gifsicle: { // 压缩 gif 的配置
interlaced: false,
},
webp: { // 开启 webp,会把 jpg 和 png 图片压缩为 webp 格式
quality: 75
},
}
yarn add image-webpack-loader
5,NamedModulesPlugin(), && HotModuleReplacementPlugin()
热模块替换相关
plugins: [ // ... new webpack.NamedModulesPlugin(), // 用于启动 HMR 时可以显示模块的相对路径 new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的插件 ],
四, 本地服务器 webpack-dev-server & webpack-dev-middleware
1, webpack-dev-server使用
添加script
"start": "webpack-dev-server --mode development"
new webpack.NamedModulesPlugin(), // 用于启动 HMR 时可以显示模块的相对路径 new webpack.HotModuleReplacementPlugin(), // Hot Module Replacement 的插件
webpack-dev-server当更多配置查看https://webpack.docschina.org/configuration/dev-server/
yarn add webpack-dev-server -D
2 ,webpack-dev-middleware使用
我们也可以使用webpack-dev-middleware 来启动静态服务器 使用如下 首先安装 webpack-dev-middleware 依赖:
npm install webpack-dev-middleware --save-dev
接着创建一个 Node.js 服务的脚本文件,如 app.js:
const webpack = require('webpack')
const middleware = require('webpack-dev-middleware')
const webpackOptions = require('./webpack.config.js') // webpack
配置文件的路径
// 本地的开发环境默认就是使用 development mode
webpackOptions.mode = 'development'
const compiler = webpack(webpackOptions)
const express = require('express')
const app = express()
app.use(middleware(compiler, {
// webpack-dev-middleware 的配置选项
}))
// 其他 Web 服务中间件
// app.use(...)
app.listen(3000, () => console.log('Example app listening on port 3000!'))
添加script
"start": "node app.js"
五,配置拆分
webpack.base.js:基础部分,即多个文件中共享的配置 webpack.development.js:开发环境使用的配置 webpack.production.js:生产环境使用的配置 因此,只要有一个工具能比较智能地合并多个配置对象,我们就可以很轻松地拆分 webpack 配置,然后通过判断环境变量,使用工具将对应环境的多个配置对象整合后提供给 webpack 使用。这个工具就是 webpack-merge。