Webpack 配置文件放置在webpack.config.js
中,
代码源码在 src/
, 文件分布结构图(使用tree ./
├── src
│ ├── css
│ │ ├── iconfont.css
│ │ └── index.less
│ ├── imgs
│ │ ├── angular.png
│ │ ├── doge.gif
│ │ ├── react.png
│ │ ├── vue.png
│ │ └── webpack.png
│ ├── index.html
│ ├── js
│ │ └── index.js
│ └── media
│ └── iconfont.ttf
└── webpack.config.js
// resolve 用来拼接绝对路径的方法
const { resolve } = require('path')
module.export = {
// webpack 配置
// 入口起点
entry: './src/js/index.js',
// 输出
output: {
// 输出文件名
filename: 'built.js',
// 输出路径
// __dirname nodejs的变量, 代表当前文件的目录的绝对路径
path: resolve(__dirname, 'build'),
},
// loader 的配置
module: {
rules: [
// 详细loader配置
],
},
// plugins的配置
plugins: [],
// 模式
mode: 'development',
}
把源码资源src
打包到build/
文件夹下
1. 编译资源(浏览器可读)
2. 压缩代码(提高加载速度)
3. 打包后资源分类(方便管理)
4. 兼容性(一次编码, 多平台互用)
处理的文件主要包括: HTML, Javascript(ES6 -> ES5), CSS(SCSS, LESS), Image(.jpg, .png, .gif), Font
- 处理style(CSS)
- loader: -style-loader- 创建
style
标签, 将JS中的样式资源插入到行中, 添加到head中生效. 我们需要把CSS与JS分离开, 所以这个loader不会再使用了 - loader: ::css-loader::把CSS文件编译成CommonJS模块, 加载到JS中, 里面的内容是 样式字符串
- loader: ::less-loader::把LESS文件编译成CSS文件
- loader: ::postcss-loader::兼容性处理
- 还需要安装plugin
postcss-preset-env
- postcss默认环境是在production. 在development, 我们需要声明node的development环境
process.env.NODE_ENV = ‘development’
postcss-preset-env
帮助postcss
找到package.json中 ::browserlist::里面的配置, 通过配置加载指定的css兼容性样式
- 还需要安装plugin
- loader: -style-loader- 创建
"browserslist": {
// 开发环境 --> 设置node环境变量: process.env.NODE_ENV = 'development'
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
// 生产环境: 默认是生产环境
"production": [
">0.2%",
"not dead",
"not op_mini all"
]
}
Postcss-loader 的配置:
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
// postcss的插件
require('postcss-preset-env')(),
],
},
}
* _plugin_: ::mini-css-extract-plugin::从`css-loader`编译后的JS中提取CSS样式字符串到指定的`filename`文件中
plugins: [
new MiniCssExtractPlugin({
// 对输出的css重命名
filename: 'css/built.css',
})
]
* _plugin_: ::optimize-css-assets-webpack-plugin::优化CSS资源(压缩CSS资源)
- 处理Image
- CSS中的图片(如: background-image: url(image_path))
- 只需要用
file-loader
就可以处理这类图片 - ::url-loader::其实内部依赖
file-loader
,url-loader
是为了可以对小图片进行base64
处理
- 只需要用
- HTML中::::中的图片
- ::html-loader::负责引入img, 从而能被
url-loader
进行处理. html-loader 并没有处理img 标签中的图片, 它只负责引入img, 处理还是用url-loader来处理的 注意:url-loader
默认使用的是::ES6模块化::解析, 而html-loader
引入图片是::CommonJS::,html-loader
引入图片后, 如果直接用url-loader
解析, 会出现图片引入为_[Object Module]_的问题. 解决: 在url-loader
设置中, 关闭url-loader
的 ES6 模块化, 使用 CommonJS 解析:esModule: false
- ::html-loader::负责引入img, 从而能被
- CSS中的图片(如: background-image: url(image_path))
- 打包HTML资源 plugin: ::html-webpack-plugin::
- 配置
template
指定模板 - 压缩HTML资源
- ::html-webpack-plugin::配置
minify
, 可以直接压缩HTML代码collapseWhitespace: true
移除空格removeComments: true
移除注释
- ::html-webpack-plugin::配置
- 配置
new HTMLWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true
}
})
- 打包其他资源(font)
- loader: ::file-loader::需要配置
exclude
排除其他已经处理的文件类型
- loader: ::file-loader::需要配置
{
exclude: /\.(html|js|css|less|scss|png|jpg|gif)$/,
loader: 'file-loader',
options: {
name: '[hash:10].[name].[ext]'
}
}
- 处理Javascript
Webpack 天生可以处理 JS/JSON 资源, 但只是处理简单的 JS(ES5). 对于JS 语法检查, JS 兼容性, JS 压缩(通过mode可以解决) 这些方面,我们还需要利用 Webpack的loader, plugins 来处理
- JS 压缩
- 当
mode: ‘production’
的时候, 可以自动压缩.
- 当
- JS 语法检查:
eslint-loader
配合使用airbnb
JS语法规范, 需要在package.json
中配置eslintConfig
- JS 压缩
"eslintConfig": {
"extends": "airbnb-base"
}
webpack.config.js
配置
{
test: /\.js$/,
loader: 'eslint-loader',
exclude: /node_modules/,
options: {
// 自动修复eslint的错误
fix: true,
},
}
* JS兼容性: `babel-loader`配合 `@babel/preset-env` `@babel/core`以及**按需加载**的`core-js`
1. 基本js兼容性处理 : `@babel/preset-env`
问题: 只能转换基本语法(处理ES6箭头函数), 对于 `promise` `proxy`高级用法无法转换
2. 高级用法可以借助 `core-js`来转换
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
// 预设: 指示babel做怎么样的兼容性处理
// presets: ['@babel/preset-env'],
presets: [
[
'@babel/preset-env',
{
// 按需加载
useBuiltIns: 'usage',
// 指定core-js版本
corejs: {
version: 3,
},
// 指定兼容性做到哪个版本浏览器
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17',
},
},
],
],
},
},
* `use` 数组中的loader遵循::FILO::(First In Last Out)调用顺序: ::从右到左::, 比如:
`use: [‘style-loader’, ‘css-loader’, ‘less-loader’]`是先调用 `less-loader` 再调用`css-loader`, 最后调用`style-loader`
* Image 有两种形式
1. CSS中使用的图片(background-image)
* 其实只使用`file-loader` 就可以处理了
* 选用`url-loader`只是为了对小图片进行`base64`编码
3. HTML 中使用的图片(img tab)
* `html-loader`用来处理HTML中`img`资源
* 注意: `html-loader`名字很奇怪, 他并不是处理整体HTML的, 只是处理HTML中的`img`资源的
3. `html-loader`采用的是`CommonJS`模块化, `url-loader`采用的是`ES6 module`模块化, 当使用`html-loader`的时候, 需要将`url-loader`中的`ES6 module`禁用掉`esModule: false`, 否则HTML中的图片不会正常被编译, 出现`[object, module]`的问题.
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const { resolve } = require('path');
// 定义nodejs环境变量: 决定使用browserslist的哪个环境
process.env.NODE_ENV = 'production';
// 复用loader
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader',
// 还需要在package.json中定义 browserslist
options: {
ident: 'postcss',
plugins: () => [require('postcss-preset-env')()],
},
},
];
module.exports = {
entry: './src/js/index.js',
output: {
filename: 'js/built.js',
path: resolve(__dirname, 'build'),
},
module: {
rules: [
{
test: /\.css$/,
use: commonCssLoader,
},
{
test: /\.less$/,
use: [...commonCssLoader, 'less-loader'],
},
/*
正常来讲, 一个文件只能被一个loader处理.
当一个文件要被多个loader处理的时候, 那么一定要指定loader执行的先后顺序
限制性eslint, 再执行babel
*/
{
// 在package.json中eslintConfig --> airbnb
test: /\.js$/,
exclude: /node_modules/,
// 优先执行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true,
},
},
{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: [
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: { version: 3 },
targets: {
chrome: '60',
firefox: 60,
},
},
],
},
{
test: /\.(jpg|png|gif)/,
loader: 'url-loader',
options: {
limit: 8 * 1024,
name: '[hash:10].[name].[ext]',
outputPath: 'imgs',
esModule: false,
},
},
{
test: /\.html$/,
loader: 'html-loader',
},
{
exclude: /\.(js|css|less|html|jpg|png|gif)/,
loader: 'file-loader',
options: {
outputPath: 'media',
},
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html',
minify: {
collapseWhitespace: true,
removeComments: true,
},
}),
new MiniCssExtractPlugin({
filename: 'css/built.css',
}),
new OptimizeCssAssetsPlugin(),
],
mode: 'production',
};
打包后得到这样的文件目录:
├── build
│ ├── imgs
│ │ ├── 077f2a8a3d.doge.gif
│ │ └── 55e1991eae.react.png
│ ├── index.html
│ ├── js
│ │ └── built.js
│ └── media
│ └── fc2b0de87e.iconfont.ttf
├── src
│ ├── css
│ │ ├── iconfont.css
│ │ └── index.less
│ ├── imgs
│ │ ├── angular.png
│ │ ├── doge.gif
│ │ ├── react.png
│ │ ├── vue.png
│ │ └── webpack.png
│ ├── index.html
│ ├── js
│ │ └── index.js
│ └── media
│ └── iconfont.ttf
└── webpack.config.js
#webpack#