webpack配置教程
webpack快速入门教程
1、webpack 介绍
- 什么是webpackhttps://www.webpackjs.com/
- Webpack是一个模块打包器(bundler)。
- 在Webpack看来, 前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理
- 它将根据模块的依赖关系进行静态分析,生成对应的静态资源
- 五个核心概念
- Entry:入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始
- Output:output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件
- Loader:loader 让 webpack 能够去处理那些非 JavaScript 文件
- Plugins:插件则可以用于执行范围更广的任务。例如:打包优化、压缩,
- Mode:模式,有生产模式 production 和开发模式 development
- 理解 Loader
- Webpack 本身只能加载 JS/JSON 模块,如果要加载其他类型的文件(模块),就需要使用对应的loader 进行转换/加载
- Loader 本身也是运行在 node.js 环境中的 JavaScript 模块
- loader 一般以 xxx-loader 的方式命名,xxx 代表了这个 loader 要做的转换功能,比如 less-loader。
- 理解 Plugins
- 插件可以完成一些loader不能完成的功能。
- 插件的使用一般是在 webpack 的配置信息 plugins 选项中指定。
- 配置文件(默认)
- webpack.config.js : 是一个node模块,返回一个 json 格式的配置信息对象
2、webpack 安装
- npm 初始化
- 安装 webpack
- npm install webpack webpack-cli -g //全局安装,作为指令使用
- npm install webpack webpack-cli -D //本地安装,作为本地依赖使用
3、编译打包应用
-
创建js文件
- src/js/app.js
- src/js/module1.js
- src/js/module2.js
- src/js/module3.js
-
创建json文件
- src/json/data.json
-
创建主页面:
- src/index.html
-
运行指令
-
开发配置指令
1
webpack src/js/app.js -o build/js/app.js --mode=development
webpack 能够编译打包 js 和 json 文件,并且能将 es6 的模块化语法转换成浏览器能识别的语法
-
生产配置指令
1
webpack src/js/app.js -o build/js/app.js --mode=production
production 配置能够压缩代码
-
-
结论:
- webpack能够编译打包 js 和 json 文件
- 能将 es6 的模块化语法进行代码打包
- 能压缩代码
-
缺点:
- 不能编译打包 css、img 等文件
- 不能将 js 的 es6 基本语法转化为 es5 语法
- 打包命令复杂
4、使用 webpack 配置文件
- 目的:在项目根目录定义配置文件,通过自定义配置文件,还原以上功能
- 文件名称:webpack.config.js
- 文件内容:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16//node内置核心模块,用来设置路径。
const { resolve } = require('path');
//只能使用 CommonJS 规范暴露
module.exports = {
// 入口文件配置
entry: './src/js/app.js',
// 输出配置
output: {
// 输出文件名
filename: './js/built.js',
//输出文件路径配置
path: resolve(__dirname, 'build')
},
// development 与 production 开发环境(二选一)
mode: 'development'
}; - 运行指令: webpack
5、打包 less 资源
less 文件 webpack 不能解析,需要借助 loader 编译解析,使用步骤如下:
- 创建less文件
- src/css/test1.less
- src/css/test2.less
- 入口app.js文件
1 | //引入两个 less 文件 |
- 安装 loader
1 | npm install css-loader style-loader less-loader less --save-dev |
-
webpack.config.js 配置 loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17module.exports = {
.
.
.
module:{
rules:[
{
test:/\.less$/, // 检查文件是否以.less结尾(检查是否是less文件)
use:[ // 数组中loader执行是从下到上,从右到左顺序执行
'style-loader', // 创建style标签,添加上js中的css代码
'css-loader', // 将css以commonjs方式整合到js文件中
'less-loader' // 将less文件解析成css文件
]
}
]
},
} -
运行指令
1
webpack
6、JS 语法检查
ESLint(https://eslint.bootcss.com/) 能对 JS 基本语法错误/隐患进行提前检查,使用步骤
-
安装loader
1
npm install eslint-loader eslint --save-dev
eslint 是语法检查的包
eslint-loader 是 eslint 在 webpack 中的 loader 包
-
webpack.config.js 配置 loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20module.exports = {
.
.
.
module: {
rules: [
.
.
.
{
test: /\.js$/, //只检测js文件
exclude: /node_modules/, //排除node_modules文件夹
enforce: "pre", //提前加载使用
use: {
loader: "eslint-loader" //使用eslint-loader解析
}
}
]
}
} -
创建
.eslintrc.js
文件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19module.exports = {
"parserOptions": {
"ecmaVersion": 6, // 支持es6
"sourceType": "module" // 使用es6模块化
},
"env": { // 设置环境
"browser": true, // 支持浏览器环境: 能够使用window上的全局变量
"node": true // 支持服务器环境: 能够使用node上global的全局变量
},
"globals": { // 声明使用的全局变量, 这样即使没有定义也不会报错了
"$": "readonly" // $ 不允许重写变量
},
"rules": { // eslint检查的规则 0 忽略 1 警告 2 错误
"no-console": 0, // 不允许出现 console
"eqeqeq": 0, // 必须使用 ===
"no-alert": 0 // 不能使用 alert
},
"extends": "eslint:recommended" // 使用eslint推荐的默认规则
} -
运行指令
1
webpack
7、JS 语法转换
借助 Babel 可以将浏览器不能识别的新语法(ES6, ES7)转换成原来识别的旧语法(ES5),浏览器兼容性处理
-
安装loader
1
npm install babel-loader @babel/core @babel/preset-env --save-dev
@babel/core 是 babel 的核心库
@babel/preset-env 是 babel 的预设的工具包,默认可以将所有最新的语法转为为 ES5
babel-loader 是 babel 在 webpack 中的 loader 包
-
配置loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17module: {
rules: [
.
.
.
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader",
options: {
presets: ['@babel/preset-env']
}
}
}
]
} -
运行指令
1 | webpack |
8、JS 兼容性处理
Polyfill 是一块代码(通常是 Web 上的 JavaScript),用来为旧浏览器提供它没有原生支持的较新的功能
-
安装 polyfill
1
npm install @babel/polyfill
-
app.js(入口文件)引入
1
import '@babel/polyfill';
解决 babel 只能转换语法的问题(如:let/const/解构赋值…),引入polyfill可以转换高级语法(如:Promise…)
9、打包样式文件中的图片资源
图片文件 webpack 不能解析,需要借助 url-loader编译解析
- 两张资源图片:
- 小图, 小于8kb: src/images/vue.png
- 大图, 大于8kb: src/images/react.jpg
-
在 less 文件中通过背景图的方式引入图片
1
2
3
4
5
6
7
8
9
10
11
12
13.react {
width: 200px;
height: 200px;
background: url('../images/react.png') no-repeat;
background-size: cover;
}
.vue {
width: 200px;
height: 200px;
background: url('../images/vue.png') no-repeat;
background-size: cover;
} -
安装 loader
1 | npm install file-loader url-loader --save-dev |
补充:url-loader是对象file-loader的上层封装,使用时需配合file-loader使用。
-
webpack.config.js 配置 loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25module.exports = {
.
.
.
module: {
rules: [
.
.
.
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 8192, // 8kb以下的图片会 base64 处理
outputPath: 'images', // 文件本地输出路径
publicPath: '../build/images', // 图片的url路径
name: '[hash:8].[ext]', // 修改文件名称和后缀
}
}
},
]
}
} -
运行指令
1
webpack
10、打包 HTML 文件
HTML 文件不能直接被 webpack 解析,需要借助 HtmlWebpackPlugin
插件编译解析
-
在 src 目录下创建 index.html 文件,==注意不要在 HTML 中引入任何 CSS 和 JS 文件==
-
安装插件
1
npm install html-webpack-plugin --save-dev
-
webpack.config.js 修改配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17// 插件都需要手动引入
const HtmlWebpackPlugin = require('html-webpack-plugin');
.
.
module.exports = {
.
.
mode: 'development',
.
.
.
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html', // 设置要编译的 HTML 源文件路径
})
]
} -
运行指令
1
webpack
src 目录就是源文件目录,所有的代码和资源都保存在该目录,index.html 也是如此
11、打包 HTML 中图片资源
url-loader 只能处理 JS 和 CSS 中引入的图片,无法处理 HTML 中的 img 图片,需要 html-loader 处理。
- src/index.html 添加 img 标签
1 | <img src="../../social/images/sun.jpg" alt=""> |
-
安装loader
1
npm install html-loader --save-dev
-
配置loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18module.exports = {
.
.
.
module: {
rules: [
.
.
.
{
test: /\.(html)$/,
use: {
loader: 'html-loader'
}
}
]
}
} -
运行指令
1
webpack
12、打包字体资源
字体文件需要借助 file-loader 编译解析,以 iconfont 为例,下载一个项目
- 将字体文件保存在
src/fonts
目录下
- src/fonts/iconfont.eot
- src/fonts/iconfont.svg
- src/fonts/iconfont.ttf
- src/fonts/iconfont.woff
- src/fonts/iconfont.woff2
-
创建 src/css/iconfont.less 并将 iconfont 的 css 样式粘到 less 文件中,并修改字体路径
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17@font-face {
font-family: 'iconfont';
src: url('../fonts/iconfont.eot');
src: url('../fonts/iconfont.eot?#iefix') format('embedded-opentype'),
url('../fonts/iconfont.woff2') format('woff2'),
url('../fonts/iconfont.woff') format('woff'),
url('../fonts/iconfont.ttf') format('truetype'),
url('../fonts/iconfont.svg#iconfont') format('svg');
}
.iconfont {
font-family: "iconfont" ;
font-size: 16px;
font-style: normal;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
} -
修改
src/index.html
1
<span class="iconfont"></span>
-
配置 loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20module.exports = {
.
.
.
module: {
rules: [
.
.
.
{
test: /\.(eot|svg|woff|woff2|ttf|mp3|mp4|avi)$/, // 处理字体文件
loader: 'file-loader',
options: {
outputPath: 'fonts',
name: '[hash:8].[ext]'
}
}
]
}
} -
运行指令
1
webpack
13、自动编译打包运行
之前的操作,每次修改代码都需要重新执行 webpack 命令,可以使用 webpack-dev-server 自动打包运行
-
安装 loader
1
npm install webpack-dev-server -g
-
修改 webpack.config.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42.
.
.
module.exports = {
.
output: {
path: resolve(__dirname, 'build'),
filename: 'js/app.js',
//1. 添加 devServer 服务后需要调整输出的路径
publicPath: '/'
},
module: {
rules: [
.
.
.
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 8192,
outputPath: 'images',
name: '[hash:8].[ext]',
//2. 删除 publicPath 配置
}
}
},
]
},
.
.
//3. 增加 devServer 配置
devServer: {
open: true, // 自动打开浏览器
compress: true, // 启动gzip压缩
port: 3000, // 端口号
},
mode: 'development'
} -
现在就可以启动服务
1
webpack-dev-server
-
配置 package.json 中 scripts 指令。增加 server 配置
1
2
3
4
5
6
7
8
9
10
11
12{
.
.
.
"scripts": {
"server": "webpack-dev-server"
},
.
.
.
}
-
运行指令
1
npm run server
14、热模替换功能
模块热替换 (HMR - Hot Module Replacement) 功能会在应用程序运行过程中替换、添加或删除模块,而无需重新加载整个页面,详细配置地址(https://www.webpackjs.com/guides/hot-module-replacement/)
修改 webpack.config.js 的 devServer 配置
1 | . |
15、devtool
devtool 配置控制 source-map 的生成 , 可以将压缩/编译文件中的代码映射回源文件中的原始位置,便于调试代码
详细配置官网地址 https://www.webpackjs.com/configuration/devtool/
配置 webpack.config.js
1 | . |
推荐使用:
- 开发环境: cheap-module-eval-source-map
- 生产环境: none source-map
16、准备生产环境
webpack 可以使用不同的配置文件,进行不同的编译。
-
创建文件夹 config,将 webpack.config.js 复制两份
- ./config/webpack.dev.js
- ./config/webpack.prod.js
-
修改 webpack.prod.js 配置,删除 webpack-dev-server 配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16.
.
.
module.exports = {
entry: {
main:['./src/js/app.js','./src/index.html']
},
.
.
.
//1. 设置 devtool
devtool: 'none',
//2. 设置 mode
mode: 'production'
//3. 删除 devServer 配置
} -
修改 package.json 的指令
1 | { |
- 开发环境指令
- npm run dev 用于开发环境 不打包文件
- npm run build 用于生产环境 打包文件 (==打包后的index.html不能直接双击打开,需要启动服务==)
17、清除打包文件目录
每次打包生成了文件,都需要手动删除,引入插件 clean-webpack-plugin
帮助我们自动删除上一次生成的文件
-
安装插件
1
npm install clean-webpack-plugin --save-dev
-
webpack.prod.js
引入插件1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17//1. 引入插件
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
.
.
.
module.exports = {
.
.
.
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
}),
//2. 配置插件
new CleanWebpackPlugin()
],
} -
运行指令
1
npm run build
18、提取 CSS 成单独文件
前面的 CSS 样式代码都是放在 style 标签中,这里可以借助 mini-css-extract-plugin 抽离 CSS 文件
-
安装插件
1
npm install mini-css-extract-plugin --save-dev
-
配置 webpack.prod.js
1 | . |
- 运行指令
1
webpack
19、添加 CSS 兼容
-
安装 loader
1
npm install postcss-loader autoprefixer --save-dev
-
配置 loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30.
.
.
module.exports = {
.
.
module: {
rules: [
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader', // 1. 设置 postcss-loader
options: {
plugins: [
require("autoprefixer") // 2. 配置插件
]
}
},
'less-loader',
]
},
.
.
]
}
} -
在项目目录下创建
.browserslistrc
==这里一要加目标浏览器设置==1
2
3
4chrome 50
last 1 versions
ie 10
iOS 7 -
运行指令:
1
npm run build
20、压缩 CSS
-
安装插件
1
npm install optimize-css-assets-webpack-plugin --save-dev
-
引入插件,配置插件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29//1. 引入插件
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
module.exports = {
plugins: [
.
.
.
//2. 配置插件
new OptimizeCssAssetsPlugin({
cssProcessorPluginOptions: {
//移除所有的注释
preset: ['default', {discardComments: {removeAll: true}}],
},
// 解决没有source map问题
cssProcessorOptions: {
map: {
// 不生成内联映射,这样配置就会生成一个source-map文件
inline: false,
// 向css文件添加source-map路径注释
// 如果没有此项压缩后的css会去除source-map路径注释
annotation: true
}
}
})
],
mode: 'production'
} -
运行指令
1
npm run build
附录
browserslist
browserslist 目标浏览器配置表,可以针对目标浏览器进行编译处理,避免不必要的兼容代码
配置的方法有两种,一种是在 package.json 中,一种是创建 .browserslistrc
package.json 形式
1 | { |
.browserslistrc
形式
1 | 1% |
配置规则介绍
规则 | 介绍 |
---|---|
> 1% | 全球超过1%人使用的浏览器 |
> 5% in US | 指定国家使用率覆盖 |
last 2 versions | 所有浏览器兼容到最后两个版本根据CanIUse.com追踪的版本 |
Firefox > 20 | 指定浏览器的版本范围 |
not ie <=8 | 排除 ie8 及以下 |
Firefox 12.1 | 指定浏览器的兼容到指定版本 |
since 2013 | 2013年之后发布的所有版本 |
not dead with > 0.2% | 仍然还在使用且使用率大于 0.2% |
last 2 Chrome versions | 最新的两个 Chrome 配置 |
cover 99.5% | 99.5% 的浏览器都是目标 |