核心概念
- 入口(entry)
- 输出(output)
- loader
- 插件(plugins)
entry
output
loader
plugins
执行任务,如打包、压缩等
配置依赖图
module.exports = {//单个入口(简写)语法entry: string|Array<string>,//对象语法entry: {[entryChunkName: string]: string|Array<string>},//基本配置output: {filename: string,path: string,},mode: string, // development|production|其他};
常用插件
- HtmlWebpackPlugin
mini-css-extract-plugin 抽离css样式
常用loader
babel-loader 转换js语法
- ESLint Loader 校验js代码
- style-loader html插入style标签
- css-loader 处理css
- postcss-loader 处理css 如加上浏览器前缀
- less-loader 处理less
- expose-loader 全局变量引入
处理JS文件
babel-loader处理js语法,eslint-loader开发环境代码校验,相关依赖包如下:
@babel/core
@babel/preset-env // es6语法
@babel/plugin-transform-runtime
@babel/plugin-proposal-decorators
@babel/plugin-proposal-class-properties
babel-loaderbabel-loader
{test: /\.m?js$/,exclude: /(node_modules|bower_components)/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],plugins: ['@babel/plugin-transform-runtime', // function *["@babel/plugin-proposal-decorators", { legacy: true }], // 解析注解"@babel/plugin-proposal-class-properties" // 解析class]}}}
eslint-loader
处理样式资源
处理图片资源
file-loader、url-loader处理文件file-loader
//es6或者CommonJS引入文件import file from "file.png";//背景图片{background-image: url("../images/1234.png");}// 配置信息{test: /\.(jpe?g|png|gif|svg)$/i,use: [{loader: 'file-loader',options: {name:'[path][name]_[hash:8].[ext]',outputPath: "/images",// publicPath: "http://www.url.cn", 生产环境cdn配置}},]},
url-loader
module.exports = {module: {test: /\.(jpe?g|png|gif|svg)$/i,use: [{loader: 'url-loader',options: {//当加载的图片小于limit时,会将图片编译成base64字符串的形式,//当图片大于这个limit,会用file-loader进行加载limit: 130000,//在webpack4.x必须显式的指定fallback备用方法,这里指定为file-loaderfallback: require.resolve('file-loader'),encoding: "base64",//这个表示在打包生成的文件的名字,如果不配置这个,会根据hash生成一个名字,这个配置就是自定义命名规则//这个表示会在输出文件夹dist下创建一个img文件夹,所有的文件会以 “原名字+hash值8位+文件扩展名”生成最终的文件来供使用name: "img/[name].[hash:8].[ext]",},}]}}
引入全局变量
打包多页面
const path = require("path");const HtmlWebpackPlugin = require("html-webpack-plugin");module.exports = {mode: "development", // development productionentry: {core: "./src/entry/core/core.js",locate: "./src/entry/locate/locate.js",},output: {filename: "[name].js",path: path.resolve(__dirname, "dist")},// HtmlWebpackPlugin 一个实例打包一个htmlplugins: [new HtmlWebpackPlugin({template: "./src/entry/core/core.html",filename: "core.html",chunks: ["core"]}),new HtmlWebpackPlugin({template: "./src/entry/locate/locate.html",filename: "locate.html",chunks: ["locate"]})]};
打包前清除打包目录文件、复制公共文档
const { CleanWebpackPlugin } = require("clean-webpack-plugin");module.exports = {plugins: [new webpack.ProgressPlugin(),new CleanWebpackPlugin(), // 清除output// 复制public 到 output目录下new CopyWebpackPlugin({patterns: [{ from: './src/public', to: './public' }]}),new HtmlWebpackPlugin({template: "./src/entry/core/core.html",filename: "core.html",chunks: ["core"]}),new HtmlWebpackPlugin({template: "./src/entry/locate/locate.html",filename: "locate.html",chunks: ["locate"]}),]}
解析文件路径
import xx from 'abc';module.exports = {resolve: {modules: ["node_modules", path.resolve(__dirname, "src")],// node_modules优先寻找mainFields: ["browser", "module", "main"], // 重abc库的package.json 配置文件中优先寻找browser// import bb from './index' 匹配index.js index.css index.vue index.jsonextensions:extensions: [".js", ".css", ".vue", ".json"],//}}
定义环境变量
DefinePlugin, webpack 内置的插件const webpack require('webpack');module.exports = {plugins: [new webpack.DefinePlugin({PRODUCTION: JSON.stringify(true),VERSION: JSON.stringify("5fa3b9"),BROWSER_SUPPORTS_HTML5: true,TWO: "1+1","typeof window": JSON.stringify("object")})]};// index.jsif (PRODUCTION) {log('11111');} else {log('22222');}
拆分配置文件
// webpack.
构建性能提升
module.noParse配置,
module.exports = {module: {noParse: /jquery/, /* import $ from "jquery" // 不解析jquery的依赖 */}}
module.rules[index] exclude、include配置
module.rules[index] = {exclude: [path.resolve(__dirname, 'node_modules')] | /node_modules/,include: [path.resolve(__dirname, 'src')] | /src/}
IgnorePlugin
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), // 不导入moment/locale 下的所有文件
DllPlugin拆分文件, 如拆分react + react-dom文件, 不必每次都打包 ```javascript // webpack.config.react.js const path = require(“path”); const wabpack = require(“webpack”); module.exports = { mode: “development”, // production、 development devServer: { port: 9015, }, entry: { react: [“react”, “react-dom”] }, output: { filename: “dll[name].js”, path: path.resolve(dirname, “dist”), library: “dll[name]”, libraryTarget: “var”, // var,commomjs,umd }, plugins: [ new wabpack.DllPlugin({ name: “dll[name]”, path: path.resolve(dirname, ‘dist’, “manifest.json”) }) ], };
// webpack.config.js const HtmlPlugin = require(“html-webpack-plugin”); const path = require(“path”); const webpack = require(“webpack”); module.exports = { mode: “development”, // production、 development devServer: { port: 9015, }, entry: { main: “./src/index.js” }, output: { filename: “[name].js”, path: path.resolve(dirname, “dist”) }, plugins: [ new HtmlPlugin({ template: “./public/index.html”, filename: “index.html” }), // 引用动态库 new webpack.DllReferencePlugin({ manifest: path.resolve(dirname, ‘dist’, ‘manifest.json’) }) ], } // src/index.js import React from “react”; import ReactDom from “react-dom”; class App extends React.Component { constructor() { super();
} render() { return (
5. happypack多线程打包看module和plugins部分```javascriptconst HtmlPlugin = require("html-webpack-plugin");const path = require("path");const webpack = require("webpack");const Happypack = require("happypack");module.exports = {mode: "development", // production、 developmentdevServer: {port: 9015,},entry: {main: "./src/index.js"},output: {filename: "[name].js",path: path.resolve(__dirname, "dist")},plugins: [new HtmlPlugin({template: "./public/index.html",filename: "index.html"}),new webpack.DllReferencePlugin({manifest: path.resolve(__dirname, 'dist', 'manifest.json')}),new Happypack({loaders: [{loader: "babel-loader",options: {presets: ["@babel/env","@babel/react",],plugins: ["@babel/plugin-proposal-class-properties"]}}]})],module: {noParse: /jquery/,rules: [{test: /\.js$/i,use: "happypack/loader",include: /src/,exclude: /node_modules/}]}};
- webpack自带优化
- 使用export import引用会自动过滤没有使用的代码,打包体积小(require不会过滤)tree-shaking
optimization抽离公共模块
module.exports = {optimization: {splitChunks: {cacheGroups: {common: {chunks: "initial",minSize: 0,minChunks: 2,// 重复两次以上},vendor: {test: /node_modules/,chunks: "initial",priority: 1,// 设置优先级 先抽离第三方minSize: 0,minChunks: 2,}}}},,}
import懒加载
import('url').then(res => {console.log(res.default);});
