webpack是一个JavaScript 应用程序的静态模块打包工具
空文件夹初始化
会生成 package.json文件
npm init -y
安装 webpack webpack-cli
npm install webpack webpack-cli --save-dev
一、入口(entry)
- 入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部 依赖图(dependency graph) 的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的
- 默认值是
./src/index.js,但是可以通过在webpack configuration中配置entry属性,来指定一个(或多个)不同的入口起点
webpack.connfig.js
module.exports = {
entry: './src/index.js'
}
1. src\index.js
import './index.css'
2. index.css
body{ background-color:green; }
二、输出(output)
output属性告诉 webpack 在哪里输出它所创建的 bundle,以及如何命名这些文件- 主要输出文件的默认值是
./dist/main.js,其他生成文件默认放置在./dist文件夹中。
webpack.config.js
+const path = require('path');
module.exports = {
entry: './src/index.js',
+ output: {
+ path: path.resolve(__dirname, 'dist'), filename: 'main.js'
+ }
};
三、loader(加载器、翻译器)
webpack 只能解析
JavaScript和JSON文件
loader 让
webpack能够去处理其他类型的文件,并将它们转换为有效模块,以供应用程序使用,以及被添加到依赖图中
loader的执行是 从右向左的,最右侧的loader是读取源文件内容的 最左侧的loader一定会返回一个js模块
1、安装 css-loader style-loader
npm install css-loader style-loader -D
2、webpack.config.js
const path = require('path');
module.exports = {
mode: 'development', devtool:false,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
+ module: {
+ rules: [
+ {
test: /\.css$/,
use: ['style-loader','css-loader'] // loader的执行是 从右向左的 最右侧的loader是读取源文件内容的 最左侧的loader一定会返回一个js模块
}
+ ]
+ }
};
四、插件(plugin)
loader 用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。包括:打包优化,资源管理,注入环境变量
模版:src\index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
</body>
</html>
安装插件HtmlWebpackPlugin
HtmlWebpackPlugin 根据模版index.html 自动引入打包后的 main.js文件
npm i html-webpack-plugin -D
webpack.config.js
const path = require('path');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'development', devtool:false,
entry: './src/index.js',
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'main.js'
},
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader','css-loader'] // loader的执行是 从右向左的 最右侧的loader是读取源文件内容的 最左侧的loader一定会返回一个js模块
}
]
},
+ plugins: [
+ new HtmlWebpackPlugin({template: './src/index.html'})
+ ]
};
打包结果
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
+ <script defer src="main.js"></script></head>
<body>
</body>
</html>
五、模式(mode)
webpack 4.x 版本引入了 mode 的概念
1 环境差异
-
开发环境
- 需要生成 sourcemap 文件
- 需要打印 debug 信息
- 需要 live reload 或者 hot reload 的功能
-
生产环境
- 可能需要分离 CSS 成单独的文件,以便多个页面共享同一个 CSS 文件
- 需要压缩 HTML/CSS/JS 代码
- 需要压缩图片
-
其默认值为 production
在不配置的情况下 console.log(process.env.NODE_ENV) 会被编译为console.log("production")
2、 如何区分环境
--mode用来设置模块内的process.env.NODE_ENV
cross-env用来设置node环境的process.env.NODE_ENV
DefinePlugin用来设置模块内的全局变量
2.1 mode配置
//webpack.config.js
module.exports = {
mode: 'development'
}
2.2 命令行配置
只能影响模块内,无法在webpack配置文件中获取此变量
//webpack.config.js
"scripts": {
"build": "webpack --mode=production",
"dev": "webpack --mode=development"
},
index.js 打印结果
console.log(process.env.NODE_ENV);// development | production
webpack.config.js 打印结果
console.log('NODE_ENV',process.env.NODE_ENV);// undefined
2.3 命令行配置
- webpack的mode默认为
production webpack serve的mode默认为development- 可以在模块内通过
process.env.NODE_ENV获取当前的环境变量,无法在webpack配置文件中获取此变量
// package.json
"scripts": {
"build": "webpack",
"dev": "webpack serve"
},
index.js 打印结果
console.log(process.env.NODE_ENV);// development | production
webpack.config.js 打印结果
console.log('NODE_ENV',process.env.NODE_ENV);// undefined
2.4 DefinePlugin插件
可以在编译时 替换源码中的字符串 不限于
process.env.NODE_ENV
- 可以在任意模块内通过
process.env.NODE_ENV获取当前的环境变量 - 但无法在
node环境(webpack 配置文件中)下获取当前的环境变量 - 键和值可以是任意
字符串只能是字符串 - 只是找到源码中存在“键”的地方都替换成“值”对应的字符串,和window无关
//webpack.config.js
plugins: [
new HtmlWebpackPlugin({ template: './src/index.html' }),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
})
]
index.js 打印结果
console.log(process.env.NODE_ENV);// development | production
webpack.config.js 打印结果
console.log('NODE_ENV',process.env.NODE_ENV);// undefined
console.log('NODE_ENV',NODE_ENV);// error !!!
2.5 cross-env
- 只能设置
node环境下的变量NODE_ENV
安装 cross-env
npm i cross-env -D
package.json 设置
"scripts": {
"build": "cross-env NODE_ENV=development webpack"
}
webpack.config.js 打印结果 及使用
const webpack = require('webpack');
console.log('process.env.NODE_ENV',process.env.NODE_ENV);// development
module.exports = {
mode: process.env.NODE_ENV,
//...
plugins: [
//...
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
})
]
}
3、 配置区分环境的步骤
3.1 安装cross-env
npm i cross-env -D
3.2 package.json 设置
"build": "cross-env NODE_ENV=development webpack"
3.3 webpack.config.js设置
const webpack = require('webpack');
module.exports = {
mode: process.env.NODE_ENV,
//...
plugins: [
//...
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
})
]
}
Q&A、webpack 和 webpack-cli 的区别
webpack 是打包的核心包
webpack-cli是命令行工具包