作用: 指示webpack 干哪些活(当你运行webpack 指令时, 会加载里面的配置) 所有构建工具都是基于node.js平台运行的-模块化默认采用common.js
const { resolve } = require('path')
// resolve用来拼接绝对路径的方法
module.exports = {
// webpack配置
// 入口起点
entry: './src/index.js',
// 输出
output: {
filename: 'bundle.js', // 输出文件名
// __dirname是node.js的变量,代表当前文件目录绝对路径
path: resolve(__dirname, 'build') // 输出路径
},
// 详细loader配置
module: {
rules: [
]
},
// plugins的配置
plugins: [],
// 模式
mode: 'development', // 开发模式
// mode: 'production',
}
- yarn add webpack webpack-cli --dev
- yarn add style-loader --dev
- yarn add css-loader --dev use 数组中loader 执行顺序, 从右到左,从下到上一次执行
-- src
--- index.css
body,html{
background: darkkhaki;
font-size: 20px;
text-align: center;
}
--- index.js
import './index.css'
import './index.less'
let element = document.createElement('h1')
element.textContent = 'Hello Webpack'
element.className = 'title'
document.body.append(element)
yarn webpack
之后我们就可以得到一个经过打包后的文件bundle.js文件
build
--bundle.js
我们在build 下新建一个index.html 将bundle.js 引入 是不是发现页面变化了, 这就是loader的作用
在webpack.config module中配置处理less的loader
- 在src文件下创建index.less 文件
.title{
color: #ffffff;
}
- yarn add less-loader less --dev
// 匹配哪些文件
{
test: /\.css$/,
use: [
// 创建style标签,将js中的样式资源插入进行
'style-loader',
'css-loader'
]
}
{
test: /\.less$/,
use: [
// 创建style标签,将js中的样式资源插入进行
'style-loader',
'css-loader',
// 将less文件编译成css 文件
'less-loader'
]
}
- 好啦,配置完成后我们执行yarn webpack 然后打开build文件下的index.html, 我们写的样式是不是有了变化, 开心!原来这么简单
- 在src 文件中创建index.html
- yarn add html-webpack-plugin --dev 我们需要导入 html-webpack-plugin,同时需要在plugin 配置HtmlWebpackPlugin
- 功能默认会创建一个空的HTML, 自动引入打包输入的所有资源
// 需要有解构的html结构
new HtmlWebpackPlugin({
template: './src/index.html'
})
- 继续执行打包命令 yarn webpack,这个时候build中的index.html会自动将js引入,直接打开html 看效果就可以啦!
- yarn add url-loader file-loader html-loader --dev
- 这里我在image 文件夹中放入一张图片
{
// 处理图片
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64处理
// 优点: 减少请求数量(减轻服务器压力)
// 缺点: 图片体积会更大(文件请求速度更慢)
limit: 10 * 1024
}
},
{
test: /\.html$/,
// 处理html文件img图片
loader: 'html-loader'
}
- 因为url-loader默认是使用es6模块化解析的,而html-loader引入图片是commonjs,解析会出现问题: [object Module],使用commonjs解析
- 关闭url-loader的es6 module esModule: false
{
// 处理图片
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64处理
// 优点: 减少请求数量(减轻服务器压力)
// 缺点: 图片体积会更大(文件请求速度更慢)
limit: 10 * 1024,
esModule: false,
// 给图片进行命名
// [hash:10] 取图片前10位
// ext取原来的扩展名
name: '[hash:10].[ext]'
}
},
- 执行yarn webpack 就可看到刚刚处理的图片资源了
这里在阿里Iconfont上下载了几个图标来进行打包
- 在src 下建立font 文件 将图标所需文件拷贝进去
- 在index.js 引入 iconfont.css
- 在webpack.config.js配置
// 打包其他资源font
{
exclude: /\.(css|js|html|less|png)$/,
loader: 'file-loader'
}
- yarn add webpack-dev-server --dev
- yarn webpack-dev-server
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true, // 启动gzip压缩
port: '3000', //端口号,
// proxy: { // 代理
// '/api': {
// // http://localhost:8080/api/users -> https: //api.github.com/api/users
// target: 'https: //api.github.com',
// // 代理路径从写
// pathRewrite: {
// '^/api': ''
// },
// changeOrigin: true
// }
// }
},
这个时候我们在修改页面的内容时就会自动打包自动编译了,是不是轻松多了?非常好的开发体验
const { resolve } = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// webpack配置
// 入口起点
entry: './src/index.js',
// 输出
output: {
filename: 'bundle.js', // 输出文件名
// __dirname是node.js的变量,代表当前文件目录绝对路径
path: resolve(__dirname, 'build') // 输出路径
},
// 开发服务器 devServer: 用来自动化 自动编译,自动打开浏览器,自动刷新浏览器
// 特点: 只会在内存中编译打包,不会有任何输出
// 启动devServer 指令位yarn webpack-dev-server
devServer: {
contentBase: resolve(__dirname, 'build'),
compress: true, // 启动gzip压缩
port: '3000', //端口号,
open: true, // 自动打开浏览器
// proxy: {
// '/api': {
// // http://localhost:8080/api/users -> https: //api.github.com/api/users
// target: 'https: //api.github.com',
// // 代理路径从写
// pathRewrite: {
// '^/api': ''
// },
// changeOrigin: true
// }
// }
},
module: {
rules: [
{
test: /\.(less)$/,
// 使用哪些loader
use: [
// use 数组中loader 执行顺序, 从右到左,从下到上一次执行
'style-loader', // 创建style标签, 将js的模式资源插入进行,添加到head 中生效
'css-loader', // 将css文件变成commonjs 模块加载到模块中,里面内容是字符串
'less-loader' // 将less文件编译成css 文件
]
},
{
test: /\.(css)$/,
// 使用哪些loader
use: [
// use 数组中loader 执行顺序, 从右到左,从下到上一次执行
'style-loader', // 创建style标签, 将js的模式资源插入进行,添加到head 中生效
'css-loader', // 将css文件变成commonjs 模块加载到模块中,里面内容是字符串
]
},
{
// 处理图片
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64处理
// 优点: 减少请求数量(减轻服务器压力)
// 缺点: 图片体积会更大(文件请求速度更慢)
limit: 10 * 1024,
esModule: false,
outputPath: 'imgs'
// 给图片进行命名
// [hash:10] 取图片前10位
name: '[hash:10].[ext]'
}
},
{
test: /\.html$/,
// 处理html文件img图片
loader: 'html-loader'
},
// 打包其他资源font
{
exclude: /\.(css|js|html|less|png)$/,
loader: 'file-loader',
options: {
// [hash:10] 取图片前10位
name: '[hash:10].[ext]'
}
}
]
},
// plugins的配置
plugins: [
// 功能默认会创建一个空的HTML, 自动引入打包输入的所有资源
// 需要有解构的html结构
new HtmlWebpackPlugin({
template: './src/index.html'
})
],
// 模式
mode: 'development', // 开发模式
// mode: 'production',
}
- css 代码压缩打包优化兼容
- 其实只要在每个use 下面的options配置outputPath就行了
options: {
outputPath: 'image'
}
- css 处理整合在js中, 导致js文件体积变大, 同时因为是先加载js,才能通过style标签插入到页面中,会出现闪屏现象。所以我们需要优化css 从js 提取出来,还要对代码同意压缩
- 样式部分js 代码兼容问题
- 当然还有很多问题要优化
- 第一能让我们的代码更好更快更强的运行, 性能更好。 各个浏览器平稳运行不会出现问题。
- 事情多,需要在生产环境进行构建
yarn add mini-css-extract-plugin --dev
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
// 我们需要将style-loader 替换成 MiniCssExtractPlugin.loader
rules: [
{
test: /\.(less|css)$/,
// 使用哪些loader
use: [
// use 数组中loader 执行顺序, 从右到左,从下到上一次执行
// MiniCssExtractPlugin取代style.loader
// 提取js中的单css 成单独文件
{
loader: MiniCssExtractPlugin.loader
},
'css-loader', // 将css文件变成commonjs 模块加载到模块中,里面内容是字符串
'less-loader' // 将less文件编译成css 文件
}
]
plugins: [
new MiniCssExtractPlugin({
filename: 'css/common.css'
})
]
- css 兼容性处理: postcss ---> yarn add postcss-loader postcss-preset-env --dev
- 使用loader 默认配置
- postcss-loader
- 修改loader 配置
- 帮postcss找到package.json 中的browserslist里面的配置,通过配置兼容指定的css 兼容性样式
// package.json 添加
// >0.2% 大于99.8
// 开发环境 设置node环境变量 process.env.NODE_ENv = development
// development开发
// prodection生产
"borwserslist": {
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
],
"prodection": [
">0.2%",
"not dead",
"not op_min all"
]
},
// 修改css loader的配置
{
loader: 'postcss-loader',
options: {
ident: 'postcss',
plugins: () => [
require('postcss-preset-env')()
]
}
}
// 执行yarn build:prod
// 兼容样式之后的代码 会默认添加-weblit-前缀
.wrapper {
width: 100px;
height: 100px;
background-color: darkseagreen;
-webkit-backface-visibility: hidden;
backface-visibility: hidden;
}
- yarn add optimize-css-assets-webpack-plugin --dev
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
plugins: [
// 压缩css
new OptimizeCssAssetsWebpackPlugin()
]
- 执行命令 yarn build:prod 就可以看到压缩后的css代码啦
-
语法检查 eslint-loader eslint
-
只检查自己写的源代码,第三方库不检查
-
设置检查规则
-
package.json 中eslintConfig中设置
-
airbnb -> eslint-config-airbnb-base eslint eslint-plugin-import --dev
-
下一行eslint 所有规则都失效
-
eslint-disable-next-line
{
test: /\.js$/,
exclude: /node_module/,
loader: 'eslint-loader',
options: {
// 自动修复
fix: true
}
}
"eslintConfig": {
extends: "airbnb-base"
}
- 生产环境下会自动压缩代码
new HtmlWebpackPlugin({
template: './src/view/index.html',
minify: {
// 移除空格
collapseWhitespace: true,
removeComments: true // 移除注释
}
}),
- 一个loader 只能被一个loader 处理
- 先执行eslint 在执行babel
const { resolve } = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin')
// 定义环境变量
process.env.NODE_ENV = 'production'
// 复用loader
const commonCssLoader = [
MiniCssExtractPlugin.loader,
'css-loader',
{
loader: 'postcss-loader', // 兼容css
options: {
ident: 'postcss',
plugins: () => [require('postcss-preset-env')()]
}
}
];
module.exports = {
entry: './src/index.js',
output: {
filename: 'js/bundle.js',
path: resolve(__dirname, 'build'),
},
module: {
rules: [
{
test: /.css$/,
use: [...commonCssLoader]
},
{
test: /.less$/,
use: [
...commonCssLoader,
'less-loader'
]
},
{
// eslint
// 在package.js eslintConfig
test: /\.js$/,
exclude: /node_modules/,
// 优先执行
enforce: 'pre',
loader: 'eslint-loader',
options: {
fix: true
}
},
{
// eslint
// 在package.js eslintConfig
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
[
'@babel/preset-env',
{
useBuiltIns: 'usage',
corejs: { version: 3 },
target: {
chorme: '60',
firefox: '50'
}
}
]
]
}
},
{
// 处理图片
test: /\.(jpg|png|gif)$/,
loader: 'url-loader',
options: {
// 图片大小小于8kb,就会被base64处理
// 优点: 减少请求数量(减轻服务器压力)
// 缺点: 图片体积会更大(文件请求速度更慢)
limit: 10 * 1024,
esModule: false,
// 给图片进行命名
// [hash:10] 取图片前10位
name: '[hash:10].[ext]',
outputPath: 'image'
}
},
{
test: /\.html$/,
// 处理html文件img图片
loader: 'html-loader',
},
// 打包其他资源font
{
exclude: /\.(css|js|html|less|png)$/,
loader: 'file-loader',
options: {
// [hash:10] 取图片前10位
name: '[hash:10].[ext]',
outputPath: 'font'
}
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
}),
new OptimizeCssAssetsWebpackPlugin(),
new HtmlWebpackPlugin({
template: './src/view/index.html',
minify: {
// 移除空格
collapseWhitespace: true,
removeComments: true // 移除注释
}
})
],
mode: 'production'
}
- 开发环境性能优化
- 生产环境性能优化
- 优化打包构建速度
- 优化代码运行的性能
- 样式文件: 可以开启HMR,在style-loader内部实现了
- js文件: 默认不能使用HMR功能
- html文件: 默认不能使用HMR功能,同时会导致问题,html文件不能更新了
- 解决: 修改entry入口,将html文件引入
entry: ['./src/js/index.js', './src/index.html']
devServer: {
hot: true
// 开启HMR功能
// 当修改了webpack 配置,新配置要想生效,必须重新启动
}
// js
if (module.hot) {
// 一旦module.hot 为true 说明开启了HMR功能
// 让HMR功能代码生效
mudule.hot.accept('./print, function() {
// 方法监听print.js文件的变化,一旦发生变化,其他默认不会重新打包
print()
})
}
- 开发环境
- source map 是一种提供源代码到构建后代码映射技术 如果后代码出错了,构建后和源代码千差万别,找代码出错位置难, 构建后代码出错了可以追踪源代码的错误,利于我们调试找出出错的原因
devtool: 'source-map'
- source-map
错误代码准确信息和源代码错误位置
- inline-source-map
错误代码准确信息和源代码错误位置
- hidden
错误代码错误原因,但是没有错误位置
不能追踪源代码错误,只能提示到构建够的代码错误位置
- eval-source-map
错误代码准确信息和源代码错误位置
- nosources-source-map
错误代码准确信息但是没有任何源代码信息
- cheap-source-map
错误代码准确信息和源代码错误位置
- cheap-module-source-map
错误代码准确信息和源代码错误位置
内联和外部的区别
1. 外部生成了文件,内联没有
2 内联构建速度极快
开发环境: 速度快,调试更友好
速度快(eval> inline> cheap)
eval-cheap-source-map
eval-source-map
调试更友好
source-map
cheap-module-source-map
cheap-source-map
结论eval-source-map -> eval-cheap-module-source-map
生产环境: 源代码要不要隐藏
nosources-source-map
hidden-source-map
内联会让代码体积变大,所以生产不建议
1 source-map
3 hidden-source-map
2 source-map
- 1
entry: {
// 多入口
main: './src/js/index.js',
test: './src/js/test.js'
}
// 输出
output: {
filename: '[name].[contenthash:10].js', // 输出文件名
// __dirname是node.js的变量,代表当前文件目录绝对路径
path: resolve(__dirname, 'build') // 输出路径
},
// 重新打包
// main.67a94b6142.js
// test.9fd198e20a.js
// 缺点 不灵活
2 optimization 可以将node_modules中的代码单独打包一个chunk最终输出 自动分析多入口chunk中,有没有公共的文件,如果有会打包成单独一个chunk
// 会输出多个js 文件代码
optimization: {
splitChunks: {
chunks: 'all'
}
}
3 单入口 + optimization 4 通过js代码,让某个文件被单独打包成一个chunk
import('./test').then(({mul,count}) => {
console.lo('加载成功')
})