webpack 4.x学习使用总结
最近一周一直都在折腾webpack,一些项目中常用的记录下来,以后免去简单的配置再去查文档。
常规
1.入口
指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。
三种写法:
entry: "./app/entry", // string | object | array entry: ["./app/entry1", "./app/entry2"], entry: { a: "./app/entry-a", b: ["./app/entry-b1", "./app/entry-b2"] },
2.出口
output 属性告诉 webpack 在哪里输出它所创建的 bundles
output:{ path: path.resolve(__dirname, "dist"), // string, filename: "bundle.js", // string filename: "[name].js", // 用于多个入口点(entry point)(出口点?) filename: "[chunkhash].js", // 用于长效缓存 publicPath: "", publicPath: "https://cdn.example.com/", }
3. 模块
开发者将程序分解成离散功能块(discrete chunks of functionality),并称之为_模块_。
module:{ rules:[{ test: /\.jsx?$/, include: [ path.resolve(__dirname, "app") ], exclude: [ path.resolve(__dirname, "app/demo-files") ], // 这里是匹配条件,每个选项都接收一个正则表达式或字符串 // test 和 include 具有相同的作用,都是必须匹配选项 // exclude 是必不匹配选项(优先于 test 和 include) // 最佳实践: // - 只在 test 和 文件名匹配 中使用正则表达式 // - 在 include 和 exclude 中使用绝对路径数组 // - 尽量避免 exclude,更倾向于使用 include issuer: { test, include, exclude }, // issuer 条件(导入源) enforce: "pre", enforce: "post", // 标识应用这些规则,即使规则覆盖(高级选项) loader: "babel-loader", // 应该应用的 loader,它相对上下文解析 // 为了更清晰,`-loader` 后缀在 webpack 2 中不再是可选的 // 查看 webpack 1 升级指南。 options: { presets: ["es2015"] }, // loader 的可选项 }] }
## 4.插件(plugins)
插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上
var webpack = require('webpack'); // 导入非 webpack 自带默认插件 var ExtractTextPlugin = require('extract-text-webpack-plugin'); var DashboardPlugin = require('webpack-dashboard/plugin'); // 在配置中添加插件 plugins: [ // 构建优化插件 new webpack.optimize.CommonsChunkPlugin({ name: 'vendor', filename: 'vendor-[hash].min.js', }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, drop_console: false, } }), new ExtractTextPlugin({ filename: 'build.min.css', allChunks: true, }), new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), // 编译时(compile time)插件 //html文件插件 new HtmlWebpackPlugin({ template: 'index.html' title: 'My App', filename: 'assets/admin.html', chunks: ['app'], excludeChunks: [ 'dev-helper' ] }) ]
5 .开发中 Server(devServer)
devServer: { //proxy: { // proxy URLs to backend development server // '/api': 'http://localhost:3000' // }, contentBase: path.join(__dirname, 'public'), // boolean | string | array, static file location compress: true, // enable gzip compression //historyApiFallback: true, // true for index.html upon 404, object for multiple paths hot: true, // hot module replacement. Depends on HotModuleReplacementPlugin //https: false, // true for self-signed, object for cert authority //noInfo: true, // only errors & warns on hot reload // ... }, devtool:'none'/'source-map' // 生产环境 devtool:'eval-source-map'//开发环境
7. externals
//配置 externals: { jquery: 'jQuery' } //代码中使用 import $ from 'jquery'; $('.my-element').animate(...);
附录
1. loader 分类列表
加载文件
raw-loader:把文本文件的内容加载到代码中去
file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件,
url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去,在
source-map-loader:加载额外的 Source Map 文件,以方便断点调试,
svg-inline-loader:把压缩后的 SVG 内容注入到代码中,
node-loader:加载 Node.js 原生模块 .node 文件。
image-loader:加载并且压缩图片文件。
json-loader:加载 JSON 文件。
yaml-loader:加载 YAML 文件。
编译模版
handlebars-loader:把 Handlebars 模版编译成函数返回。
markdown-loader:把 Markdown 文件转换成 HTML。
转换脚本语言
babel-loader:把 ES6 转换成 ES5,在3-1使用 ES6 语言中有介绍。
ts-loader:把 TypeScript 转换成 JavaScript,在3-2使用 TypeScript 语言中有遇到。
awesome-typescript-loader:把 TypeScript 转换成 JavaScript,性能要比 ts-loader 好。
coffee-loader:把 CoffeeScript 转换成 JavaScript。
转换样式文件
css-loader:加载 CSS,支持模块化、压缩、文件导入等特性。
style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。
sass-loader:把 SCSS/SASS 代码转换成 CSS,在3-4使用 SCSS 语言中有介绍。
postcss-loader:扩展 CSS 语法,使用下一代 CSS,在3-5使用 PostCSS中有介绍。
less-loader:把 Less 代码转换成 CSS 代码。
stylus-loader:把 Stylus 代码转换成 CSS 代码。
检查代码
eslint-loader:通过 ESLint 检查 JavaScript 代码,在 3-16检查代码中有介绍。
tslint-loader:通过 TSLint 检查 TypeScript 代码。
mocha-loader:加载 Mocha 测试用例代码。
coverjs-loader:计算测试覆盖率。
其它
vue-loader:加载 Vue.js 单文件组件,在3-7使用 Vue 框架中有介绍。
i18n-loader:加载多语言版本,支持国际化。
ignore-loader:忽略掉部分文件,在3-11构建同构应用中有介绍。
ui-component-loader:按需加载 UI 组件库,例如在使用 antd UI 组件库时,不会因为只用到了 Button 组件而打包进所有的组件。
2.常用 Plugins
用于修改行为
context-replacement-plugin:修改 require 语句在寻找文件时的默认行为。
ignore-plugin:用于忽略部分文件。
用于优化
extract-text-webpack-plugin:提取 JavaScript 中的 CSS 代码到单独的文件中
prepack-webpack-plugin:通过 Facebook 的 Prepack 优化输出的 JavaScript 代码性能,
uglifyjs-webpack-plugin:通过 UglifyES 压缩 ES6 代码,
webpack-parallel-uglify-plugin:多进程执行 UglifyJS 代码压缩,提升构建速度。
imagemin-webpack-plugin:压缩图片文件。
webpack-spritesmith:用插件制作雪碧图。
ModuleConcatenationPlugin:开启 Webpack Scope Hoisting 功能,
dll-plugin:借鉴 DDL 的思想大幅度提升构建速度,
hot-module-replacement-plugin:开启模块热替换功能。
其它
serviceworker-webpack-plugin:给网页应用增加离线缓存功能,在
stylelint-webpack-plugin:集成 stylelint 到项目中,
i18n-webpack-plugin:给你的网页支持国际化。
provide-plugin:从环境中提供的全局变量中加载模块,而不用导入对应的文件。
web-webpack-plugin:方便的为单页应用输出 HTML,比 html-webpack-plugin 好用。
配置汇总
var path = require('path') var webpack = require('webpack') //性能分分析 const WebpackMonitor = require("webpack-monitor"); const HtmlWebpackPlugin = require('html-webpack-plugin'); var ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { mode: ' "production" | "development" | "none"', entry: { a: "./app/entry-a", b: ["./app/entry-b1", "./app/entry-b2"] }, output: { path: path.resolve(__dirname, "dist"), // string, filename: "bundle.js", // string filename: "[name].js", // 用于多个入口点(entry point)(出口点?) filename: "[chunkhash].js", // 用于长效缓存 publicPath: "", publicPath: "https://cdn.example.com/" }, module: { rules: [ { test: /\.js$/, loader: 'babel-loader', exclude: /node_modules/ }, { // 用正则去匹配要用该 loader 转换的 CSS 文件 test: /\.css$/, use: ExtractTextPlugin.extract({ use: ['style-loader', 'css-loader', 'postcss-loader'], include: path.join(__dirname, './src'), exclude: /node_modules/ }) }, { test: /\.(png|jpg|gif|svg|bmp|eot|woff|woff2|ttf)$/, loader: { loader: 'file-loader', options: { name: '[name].[ext]?[hash]' } } }, { test: /\.(png|jpg|gif|svg|bmp|eot|woff|woff2|ttf)$/, loader: { loader: 'url-loader', options: { limit: 5 * 1024, // 图片大小 > limit 使用file-loader, 反之使用url-loader outputPath: 'images/' // 指定打包后的图片位置 } } }, { // 暴露模块 test: require.resolve('jquery'), // 注意 这里是require的resolve 方法 use: { loader: 'expose-loader', options: '$' } } ] }, plugins: [ // 构建优化插件 new webpack.optimize.CommonsChunkPlugin({ name: "vendor", filename: "vendor-[hash].min.js" }), new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, drop_console: false } }), //提取css文件 new ExtractTextPlugin({ filename: "build.min.css", allChunks: true }), new WebpackMonitor({ capture: true, // -> default 'true' target: "../monitor/myStatsStore.json", // default -> '../monitor/stats.json' launch: true, // -> default 'false' port: 3030 // default -> 8081 }), //html文件插件 new HtmlWebpackPlugin({ template: "index.html", title: "My App", filename: "assets/admin.html", chunks: ["app"], excludeChunks: ["dev-helper"] }) ], devServer: { //proxy: { // proxy URLs to backend development server // '/api': 'http://localhost:3000' // }, contentBase: path.join(__dirname, "public"), // boolean | string | array, static file location compress: true, // enable gzip compression //historyApiFallback: true, // true for index.html upon 404, object for multiple paths hot: true // hot module replacement. Depends on HotModuleReplacementPlugin //https: false, // true for self-signed, object for cert authority //noInfo: true, // only errors & warns on hot reload // ... }, devtool: "eval-source-map", //开发环境 //配置 externals: { jquery: "jQuery" } };
其他
设置淘宝npm镜像
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
vm 适配
cnpm i postcss-import postcss-url autoprefixer postcss-aspect-ratio-mini postcss-px-to-viewport postcss-write-svg postcss-cssnext cssnano postcss-viewport-units cssnano-preset-advanced -D npm install viewport-units-buggyfill var hacks = require('viewport-units-buggyfill/viewport-units-buggyfill.hacks'); require('viewport-units-buggyfill').init({ hacks: hacks });