webpack 配置
官网 www.webpackjs.com/concepts/
官网配置 webpack.js.org/configurati…
一、起步
-
我们选择局部安装 webpack webpack-cli
- webpack 4.+ 需要安装 webpack-cli
npm i webpack webpack-cli
-
因为是局部安装的,可以在 package.json 里面配置 脚本命名
"scripts": { "build": "webpack --mode development", }- 这样就可以运行
npm run build来启用webpack了
- 这样就可以运行
-
我们需要新建入口文件,webpack默认入口文件是
./src/index.js- 新建好后就可以运行
npm run build来看看webpack为我们做了什么了
- 新建好后就可以运行
-
webpack-dev-server
- 起一个开发服务器
- 用来访问打包好的 html、css、js
- 配置
- package.json
"dev": "webpack-dev-server --mode development --config build/webpack.config.js",- webpack.config.js 配置 devserver 的详细
- 运行
npm run dev
二、webpack的配置文件
webpack 默认配置文件为根目录下的 webpack.config.js
- entry / output
- 单入口 单出口
entry: './src/index.js', //默认的入口文件 output: { // 【不写 默认是 dist/main.js】 path: path.resolve(__dirname,'dist'), // 输出目录 用到了 path模块需要导入 【默认不写就是 根目录/dist】 filename: 'main.js' //输出文件名 }- 多入口 多出口
/* webpack 自带 变量 name: 表示跟入口文件同名,入口文件为对象形式时,就是对象的key hash: 表示hash值 这个是全局hash (不合理,我们使用chunkHash代替) hash:5 表示截取前5位 chunkHash: 根据文件不同生成的也不一样 contentHash: 不怎么用 */ entry: { // 多个入口 home: './src/home.js', about: './src/about.js' }, output: { path: path.resolve(__dirname,'dist'), filename: '[name].[hash:5].js' // 【不写默认跟入口文件同名】 }
三、配置一个基本的开发环境
const path = require('path')
module.exports = {
entry: {
index: './src/index.js'
},
output: {
path: path.resolve(process.cwd(),'dist'),
filename: '[name].[chunkHash:5].js'
}
}
3.1 处理html
- html-webpack-plugin 自动打包html文件
3.2 处理 css
-
css-loader
- 使用
css-loader的时候 还需要安装style-loadercss-loader我们在入口js文件导入 css文件后css-loader负责打包 把css文件整合到打包好的 js文件中style-loader负责吧打包好的js文件里的css 文件 在html文件中创建 style 标签并插入
module.exports = { module: { rules: [ { test: /\.css$/i, use: ['style-loader', 'css-loader'], }, ], }, }; - 使用
-
mini-css-extract-plugin
- webpack 4.+ 起
- 因为
css-loader打包的 css文件都是插入到页面 style的内联样式,如果需要生成一个单独的外部css样式文件需要使用它来打包
-
extract-text-webpack-plugin
- webpack 4 以前
- 同
mini-css-extract-plugin
-
less-loader
- 安装 less-loader 还需要 安装 less
npm i less-loader less -S
-
postcss-loader
- 给样式自动加前缀,需要 autoprefixer 配合使用
- 步骤
npm install postcss-loader autoprefixer -S- 需要在
css-loader之前使用,use里面是从下往上的顺序使用
rules: [ { test: /\.less$/, // 处理 less use: [ MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', // 自动添加前缀 还需配合 autoprefixer 'less-loader' ], } ]- 根目录下新建 postcss.config.js
module.exports = { plugins: [ require('autoprefixer') ] } - 结果
::-moz-placeholder { color: #aaa; } :-ms-input-placeholder { color: #aaa; } ::-ms-input-placeholder { color: #aaa; } ::placeholder { color: #aaa; } - 注意:
- 对于flex 如果我们要让其自动加上前缀,则需要使用到browserslist;
package.json里面加入
"browserslist": [ "cover 99.5%" ] - browserslist 调用的是 caniuse 里面的 api
- 对于flex 如果我们要让其自动加上前缀,则需要使用到browserslist;
package.json里面加入
3.3 处理图片资源
- 只针对js里面 import的css里面用到的图片,html标签的图片不会进行处理
- file-loader
- 直接拷贝图片资源
- 使用的时候要注意打包后的路径变化
{ test: /\.(png|jpe?g|gif)$/i, use: [ { loader: 'file-loader', options: { name: 'static/images/[name].[ext]', publicPath: '/' }, }, ], } - url-loader
- 也可处理图片资源
- 特点: 通过配置项来进行 图片 base64 转换处理
{ test: /\.(png|jpe?g|gif)$/i, use: [ // 方法1: file-loader 处理图片资源 // { // loader: 'file-loader', // options: { // name: 'static/images/[name].[ext]', // publicPath: '/' // } // }, // 方法2: url-loader 处理图片资源 base64 处理 { loader: 'url-loader', options: { limit: 1024*130, // 图片大小没有超过 130kb 时 直接转成 base64 处理 // 下面两行时图片大小超过了 limit的值时的处理方式,把图片放在/static/images/图片名.图片拓展名 name: 'static/images/[name].[ext]', publicPath: '/' } } ], },
3.4 拷贝文件资源
- copy-webpack-plugin
const CopyPlugin = require('copy-webpack-plugin');
new CopyPlugin({
patterns: [
{
from: path.resolve(process.cwd(),'src/static'),
to:path.resolve(process.cwd(),'dist/static')
}
],
}),
3.5 添加babel es6 转 es5
- babel-loader
$ npm install -D babel-loader @babel/core @babel/preset-env
rules: [ { test: /\.m?js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: ['@babel/preset-env'] } } } ]
3.6 拆分webpack.config.js
- 需要用到
webpack-merge$ npm i webpack-merge
- 我们
npm run build和npm run dev使用的是同一个webpack.config.js文件,现在对其拆分并把公共部分提取出来- webpack.dev.js
- webpack.prod.js
- webpack.common.js
- webpack.config.js
- 步骤
// webpack.dev.js const common = require('./webpack.common.js') const { merge } = require('webpack-merge') module.exports = merge(common, { // 写 dev环境才需要的配置 , eg: devServer: { port: 9000 } ... })
四、一个webpack的配置
- package.json
{
"name": "webpack-get-start",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "webpack --env production --config build/webpack.config.js",
"dev": "webpack-dev-server --env development --config build/webpack.config.js",
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "Bolo",
"license": "MIT",
"devDependencies": {
"@babel/core": "^7.11.1",
"@babel/preset-env": "^7.11.0",
"babel-loader": "^8.1.0",
"clean-webpack-plugin": "^3.0.0",
"copy-webpack-plugin": "^6.0.3",
"cross-env": "^7.0.2",
"css-loader": "^4.2.1",
"file-loader": "^6.0.0",
"html-webpack-plugin": "^4.3.0",
"mini-css-extract-plugin": "^0.10.0",
"style-loader": "^1.2.1",
"url-loader": "^4.1.0",
"webpack": "^4.44.1",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
},
"dependencies": {
"autoprefixer": "^9.8.6",
"less": "^3.12.2",
"less-loader": "^6.2.0",
"postcss-loader": "^3.0.0",
"webpack-merge": "^5.1.1"
},
"browserslist": [
"cover 99.5%"
]
}
- webpack.config.js
const commonConfig = require('./webpack.common.js');
const productionConfig = require('./webpack.prod.js');
const developmentConfig = require('./webpack.dev.js');
const { merge } = require('webpack-merge')
module.exports = env => { // env 需要通过 package.json 传入
console.log('boloooo',env)
switch (env) {
case 'development':
return merge(commonConfig, developmentConfig);
case 'production':
return merge(commonConfig, productionConfig);
default:
throw new Error('No matching configuration was found!');
}
}
- webpack.common.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
entry: {
index: './src/index.js'
},
output: {
path: path.resolve(process.cwd(), 'dist'),
filename: '[name].[chunkHash:5].js'
},
plugins: [
new HtmlWebpackPlugin({
title: 'webpack - leaning',
template: 'src/public/index.html'
}),
new CleanWebpackPlugin({
cleanOneceBeforeBuildPatterns: ['./dist']
}),
new CopyPlugin({
patterns: [
{
from: path.resolve(process.cwd(), 'src/static'),
to: path.resolve(process.cwd(), 'dist/static')
},
]
}),
],
module: {
rules: [
// 图片资源的处理 common
{
test: /\.(png|jpe?g|gif)$/i,
use: [
{
loader: 'url-loader',
options: {
limit: 1024 * 130,
name: 'images/[name].[ext]',
publicPath: '/'
}
}
],
},
// babel common
{
test: /\.m?js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}
- webpack.dev.js
module.exports = {
mode: 'development',
module: {
rules: [
// 处理 css 文件
{
test: /\.css$/,
use: [
'style-loader',
'css-loader',
],
},
// 处理 less 文件 mode:dev -- style-loader
{
test: /\.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
],
}
]
},
devServer: {
port: 9000,
open: true
}
}
- webpack.prod.js
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
module.exports = {
mode: 'production',
plugins: [
new MiniCssExtractPlugin({
filename: 'css/[name].css'
})
],
module: {
rules: [
// 处理 css 文件
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
],
},
// 处理 less 文件
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader', // 自动添加前缀 还需配合 autoprefixer
'less-loader'
],
}
]
},
}
补充
1. 什么是hash值
通过一定的哈希算bai法(典型的有MD5,SHA-1等),将一段较长的数据映射为较zhi短小的数据,这段小数据就是大数据的哈希值。他有这样一个特点,他是唯一的,一旦大数据发生了变化,哪怕是一个微小的变化,他的哈希值也会发生变化。
2. package.json 里面启动webpack时的配置
- mode
- 模式 development/production
--mode development
- config
- 指定webpack的配置文件路径
--config configs/webpack.config.js- 注意: 如果改变了配置文件的路径, output 时如果用
__dirname就会指定 dist 在当前目录下了,如果还需要指定在根目录下,需要这样写path: path.resolve(process.cwd(),'dist')
- env
3. 启动时给某变量赋值,并可在webpack.config.js 访问
"dev": "webpack-dev-server --config build/webpack.config.js",
- 方法1 : 使用
--env 值"dev": "webpack-dev-server --env development --config build/webpack.js",console.log(env) // 'development'
"dev": "webpack-dev-server --env.NODE_ENV development --config build/webpack.js",console.log(env) // {NODE_ENV:'development'}
- 方法2: 使用
cross-env第三方依赖- 安装依赖
- 传入 NODE_ENV=development
"scripts": { "start": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.config.js", "build": "cross-env NODE_ENV=production webpack --config ./build/webpack.config.js" }, - webpack.config.js 获取的时候可以使用
process.env.NODE_ENV去获取-
devtool: process.env.NODE_ENV === 'production' ? false : 'inline-source-map',
-