webpack基础

安装

1
2
3
4
# 初始化项目
npm init -y
# 安装
npm install -g/-D webpack webpack-cli

五大核心概念

入口

入口起点(entry point) 指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

webpack.config.js

1
2
3
4
module.exports = {
// 使用相对路径
entry: './src/index.js',
}

输出

output 属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件。主要输出文件的默认值是 ./dist/main.js,其他生成文件默认放置在 ./dist 文件夹中。

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12

// 引入 nodejs 核心模块 path
const path = require('path')

module.exports = {
output: {
// filename 用于输出文件的文件名
filename: 'bundle.js',
// 目标输出目录 path 的绝对路径,使用path.join()拼接路径,nodejs 全局变量 __dirname
path: path.join(__dirname, './dist'),
}
}

loaders

webpack 只能理解 JavaScript 和 JSON 文件,这是 webpack 开箱可用的自带能力。loader 让 webpack 能够去处理其他类型的文件,并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。

首先,安装对应的 loader

1
2
npm install --save-dev css-loader
npm install --save-dev ts-loader

然后指示 webpack 对每个 .css 使用 css-loader,以及所有 .ts 文件使用 ys-loader

三种方式

配置方式

webpack.config.js

1
2
3
4
5
6
7
8
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' },
]
}
}

内联方式

1
import Styles from 'style-loader!css-loader?modules!./styles.css';

loader 特性

  • loader 支持链式调用。链中的每个 loader 会将转换应用在已处理过的资源上。一组链式的 loader 将按照相反的顺序执行。链中的第一个 loader 将其结果(也就是应用过转换后的资源)传递给下一个 loader,依此类推。最后,链中的最后一个 loader,返回 webpack 所期望的 JavaScript。
  • loader 可以是同步的,也可以是异步的。
  • loader 运行在 Node.js 中,并且能够执行任何操作。
  • loader 可以通过 options 对象配置(仍然支持使用 query 参数来设置选项,但是这种方式已被废弃)。
  • 除了常见的通过 package.json 的 main 来将一个 npm 模块导出为 loader,还可以在 module.rules 中使用 loader 字段直接引用一个模块。
  • 插件(plugin)可以为 loader 带来更多特性。
  • loader 能够产生额外的任意文件。

plugins

安装插件

1
npm install --save-dev html-webpack-plugin

基本用法

1
2
3
4
5
6
7
8
9
10
11
12
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
// 与配置文件平级的一个html
template: 'template.html'
})
],
};

这将会生成一个包含以下内容的 dist/index.html 文件:

1
2
3
4
5
6
7
8
9
10
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>webpack App</title>
</head>
<body>
<script src="index_bundle.js"></script>
</body>
</html>

HMR-模块热替换(hot module replacement)

安装

1
npm install webpack-dev-server --save-dev

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const webpack = require('webpack')

module.exports = {
devServer: {
contentBase: './dist',
hot: true
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
// 与配置文件平级的一个html
template: 'template.html'
}),
new webpack.HotModuleReplacementPlugin()
],
};

package.json

1
2
3
4
5
"scripts": {
"build": "webpack",
"watch": "webpack --watch",
"hot": "webpack-dev-server"
}

模式

通过选择 development, production 或 none 之中的一个,来设置 mode 参数,你可以启用 webpack 内置在相应环境下的优化。其默认值为 production

1
2
3
module.exports = {
mode: 'development',
}

development 比 production大

NODE_ENV

参考

NODE_ENV是一个由 Node.js 暴露给执行脚本的系统环境变量。通常用于确定在开发环境还是生产环境(dev-vs-prod)下,服务器工具、构建脚本和客户端 library 的行为。

NODE_ENV会赋值给 process.env 对象,作为它的一个属性,其值通常为“production”(生产环境)和“development”(开发环境),或者“prod”和“dev”,以此来区分不同环境下的逻辑行为.

1
2
3
4
5
6
7
if(process.env.NODE_ENV === 'development'){ 
//开发环境 do something
console.log('baseurl is localhost')
}else{
//生产环境 do something
console.log('baseurl is www.xxx.com')
}

babel

1
2
npm install babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime -D
npm install @babel/runtime -S

.babelrc

1
2
3
4
5
6
7
8
{
"presets": [
"@babel/preset-env"
],
"plugins": [
"@babel/plugin-transform-runtime"
]
}

webpack.config.js

1
2
3
4
5
6
7
8
9
module.exports = {
module: {
rules: [
{ test: /\.css$/, use: 'css-loader' },
{ test: /\.ts$/, use: 'ts-loader' },
{ test: /\.js$/, use: 'babel-loader' },
]
}
}

clean-webpack-plugin 和 copy-webpack-plugin

1
npm install clean-webpack-plugin copy-webpack-plugin -D

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
const { CopyWebpackPlugin } = require('copy-webpack-plugin')

module.exports = {
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
// 与配置文件平级的一个html
template: 'template.html'
}),
new webpack.HotModuleReplacementPlugin(),
new CleanWebpackPlugin(),
new CopyWebpackPlugin({
from: path.join(__dirname, 'assets'),
to: 'assets'
})
],
}

optimize-css-assets-webpack-plugin 和 terser-webpack-plugin

1
2
npm install optimize-css-assets-webpack-plugin terser-webpack-plugin -D
npm install mini-css-extract-plugin -D

webpack.config.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
const TerserJSPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');

module.exports = {
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})]
},
plugins: [
new MiniCssExtractPlugin({
filename: '[name].css',
chunkFilename: '[id].css'
})
],
module: {
rules: [
test: /\.css$/,
use: [MiniCssExtractPlugin.loader, 'css-loader']
]
}
}