一个合格的Webpack4配置工程师素养:第三部分
栏目: JavaScript · 发布时间: 5年前
内容简介:之前有提过webpack根据不同的环境我们会加载不同的配置。我们只需要提取出三部分。我们这里现在简单分层:正式项目最好创建一个config/webpack目录管理。下面是源代码。
之前有提过webpack根据不同的环境我们会加载不同的配置。我们只需要提取出三部分。
- base: 公共的部分 - dev: 开发环境部分 - prod: 生产环境部分 复制代码
npm i -D webpack-merge 复制代码
我们这里现在简单分层:正式项目最好创建一个config/webpack目录管理。
下面是源代码。
"scripts": { "dev": "cross-env NODE_ENV=development npx webpack --progress --config webpack.dev.config.js", "build": "cross-env NODE_ENV=production npx webpack --progress --config webpack.prod.config.js" }, 复制代码
// webapck.base.config.js const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin') const CleanWebpackplugin = require('clean-webpack-plugin') module.exports = { entry: './src/index.js', module: { rules: [ // 处理字体 { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { // 文件大小小于limit参数,url-loader将会把文件转为DataUR limit: 10000, name: '[name]-[hash:5].[ext]', output: 'fonts/', // publicPath: '', 多用于CDN } }, // 处理文件 { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, use: [ // 转base64 { loader: 'url-loader', options: { // 具体配置见插件官网 limit: 10000, name: '[name]-[hash:5].[ext]', outputPath: 'img/', // outputPath所设置的路径,是相对于 webpack 的输出目录。 // publicPath 选项则被许多webpack的插件用于在生产模式下更新内嵌到css、html文件内的 url , 如CDN地址 }, }, { loader: 'image-webpack-loader', options: { mozjpeg: { progressive: true, quality: 65 }, // optipng.enabled: false will disable optipng optipng: { enabled: false, }, pngquant: { quality: '65-90', speed: 4 }, gifsicle: { interlaced: false, }, // the webp option will enable WEBP webp: { quality: 75 } } } ] } ] }, plugins: [ // 打包模板 new HtmlWebpackPlugin({ inject: true, hash: true, cache: true, chunksSortMode: 'none', title: 'Webapck4-demo', // 可以由外面传入 filename: 'index.html', // 默认index.html template: path.resolve(__dirname, 'index.html'), minify: { collapseWhitespace: true, removeComments: true, removeRedundantAttributes: true, removeScriptTypeAttributes: true, removeStyleLinkTypeAttributes: true } }), // 清理dist目录 new CleanWebpackplugin(['dist']) ] } 复制代码
// webpack.dev.config.js const path = require('path') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.config.js') module.exports = merge(baseWebpackConfig, { mode: 'development', output: { filename: 'bound.js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ // 处理css/scss/sass { test: /\.(sc|sa|c)ss$/, use: [ { loader: 'style-loader', }, { loader: 'css-loader', options: { sourceMap: true } }, { loader: 'postcss-loader', options: { ident: 'postcss', sourceMap: true, plugins: (loader) => [ require('autoprefixer')({ browsers: [ 'last 10 Chrome versions', 'last 5 Firefox versions', 'Safari >= 6', 'ie > 8' ] }) ] } }, { loader: 'sass-loader', options: { sourceMap: true } } ] } ] } }) 复制代码
// webapck.prod.config.js const path = require('path') const MiniCssExtractPlugin = require('mini-css-extract-plugin') const OptimizeCSSAssertsPlugin = require('optimize-css-assets-webpack-plugin') const TerserPlugin = require('terser-webpack-plugin') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.config.js') const devMode = process.env.NODE_ENV !== 'production' module.exports = merge(baseWebpackConfig, { mode: 'production', output: { filename: 'bound.[hash:5].js', path: path.resolve(__dirname, 'dist') }, module: { rules: [ // 处理css/scss/sass { test: /\.(sc|sa|c)ss$/, use: [ MiniCssExtractPlugin.loader, { loader: 'css-loader' }, { loader: 'postcss-loader', options: { ident: 'postcss', plugins: (loader) => [ require('autoprefixer')({ browsers: [ 'last 10 Chrome versions', 'last 5 Firefox versions', 'Safari >= 6', 'ie > 8' ] }) ] } }, { loader: 'sass-loader' } ] } ] }, plugins: [ // 提取CSS new MiniCssExtractPlugin({ filename: devMode ? '[name].css' : '[name].[hash:5].css', // 设置输出的文件名 chunkFilename: devMode ? '[id].css': '[id].[hash:5].css' }) ], optimization: { minimizer: [ // 压缩JS new TerserPlugin({ cache: true, parallel: true, sourceMap: true, // 等等详细配置见官网 }), // 压缩CSS new OptimizeCSSAssertsPlugin({}) ] } }) 复制代码
webpack配置js使用sourceMap
在webpack4使用inline-source-map选项就可以启动错误的堆栈跟踪, 只用于开发环境
devtool: 'inline-source-map' 复制代码
监控文件变化自动编译
简单的方法就是启动watch模式: 如
"dev": "cross-env NODE_ENV=development npx webpack --progress --config webpack.dev.config.js --watch" 复制代码
webpack开启热更新和代理配置
很明显上面watch模式效率不高而且很不方便, 编译完还需要刷新页面, webpack可以开启热更新模式,大大加速开大效率。
npm i -D webpack-dev-server 复制代码
修改script脚本。
"dev": "cross-env NODE_ENV=development npx webpack-dev-server --progress --config webpack.dev.config.js" 复制代码
修改配置文件
const webpack = require('webpack') plugins: [ new webpack.NamedModulesPlugin(), // 更方便查看patch的依赖 new webpack.HotModuleReplacementPlugin() // HMR ], devServer: { clientLogLevel: 'warning', // 输出日志级别 hot: true, // 启用热更新 contentBase: path.resolve(__dirname, 'dist'), // 告诉服务器从哪里提供内容 publicPath: '/', // 此路径下的打包文件可在浏览器下访问 compress: true, // 启用gzip压缩 // publicPath: './', disableHostCheck: true, host: '0.0.0.0', port: 9999, open: true, // 自动打开浏览器 overlay: { // 出现错误或者警告时候是否覆盖页面线上错误信息 warnings: true, errors: true }, quiet: true, proxy: { // 设置代理 '/dev': { target: 'http://dev.xxxx.com.cn', changeOrigin: true, pathRewrite: { '^/dev': '' } /** * 如果你的配置是 * pathRewrite: { '^/dev': '/order/api' } 即本地请求 /dev/getOrder => 实际上是 http://dev.xxxx.com.cn/order/api/getOrder */ }, '/test': { target: 'http://test.xxxx.com.cn', changeOrigin: true, pathRewrite: { '^/test': '' } }, '/prod': { target: 'http://prod.xxxx.com.cn', changeOrigin: true, pathRewrite: { '^/prod': '' } } }, watchOptions: { // 监控文件相关配置 poll: true, ignored: /node_modules/, // 忽略监控的文件夹, 正则 aggregateTimeout: 300, // 默认值, 当你连续改动时候, webpack可以设置构建延迟时间(防抖) } } 复制代码
webpack启用babel转码
npm i -D babel-loader @babel/core @babel/preset-env @babel/runtime @babel/plugin-transform-runtime 复制代码
修改配置文件
// 编译js { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader?cacheDirectory', // 通过cacheDirectory选项开启支持缓存 options: { presets: ['@babel/preset-env'] } } }, 复制代码
增加.babelrc配置文件
// 仅供参考 { "presets": [ [ "@babel/preset-env" ] ], "plugins": [ [ "@babel/plugin-transform-runtime", { "corejs": false, "helpers": true, "regenerator": true, "useESModules": false, "absoluteRuntime": "@babel/runtime" } ] ] } 复制代码
webpack配置eslint校验
npm i -D eslint eslint-loader // 校验规则 npm i -D babel-eslint standard 复制代码
修改webpack配置文件
// 编译js { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: [ { loader: 'babel-loader?cacheDirectory', // 通过cacheDirectory选项开启支持缓存 options: { presets: ['@babel/preset-env'] } }, { loader: 'eslint-loader', options: { fix: true } } ] }, 复制代码
增加.eslintrc.js文件
/* * ESLint的JSON文件是允许JavaScript注释的,但在gist里显示效果不好,所以我把.json文件后缀改为了.js */ /* * ESLint 配置文件优先级: * .eslintrc.js(输出一个配置对象) * .eslintrc.yaml * .eslintrc.yml * .eslintrc.json(ESLint的JSON文件允许JavaScript风格的注释) * .eslintrc(可以是JSON也可以是YAML) * package.json(在package.json里创建一个eslintConfig属性,在那里定义你的配置) */ /* * 你可以通过在项目根目录创建一个.eslintignore文件告诉ESLint去忽略特定的文件和目录 * .eslintignore文件是一个纯文本文件,其中的每一行都是一个glob模式表明哪些路径应该忽略检测 */ module.exports = { //ESLint默认使用Espree作为其解析器 //同时babel-eslint也是用得最多的解析器 //parser解析代码时的参数 "parser": "babel-eslint", "parserOptions": { //指定要使用的ECMAScript版本,默认值5 "ecmaVersion": 6 //设置为script(默认)或module(如果你的代码是ECMAScript模块) // "sourceType": "script", //这是个对象,表示你想使用的额外的语言特性,所有选项默认都是false // "ecmafeatures": { // //允许在全局作用域下使用return语句 // "globalReturn": false, // //启用全局strict模式(严格模式) // "impliedStrict": false, // //启用JSX // "jsx": false, // //启用对实验性的objectRest/spreadProperties的支持 // "experimentalObjectRestSpread": false // } }, //指定环境,每个环境都有自己预定义的全局变量,可以同时指定多个环境,不矛盾 "env": { //效果同配置项ecmaVersion一样 "es6": true, "browser": true, "node": true, "commonjs": false, "mocha": true, "jquery": true, //如果你想使用来自某个插件的环境时,确保在plugins数组里指定插件名 //格式为:插件名/环境名称(插件名不带前缀) // "react/node": true }, //指定环境为我们提供了预置的全局变量 //对于那些我们自定义的全局变量,可以用globals指定 //设置每个变量等于true允许变量被重写,或false不允许被重写 "globals": { "globalVar1": true, "globalVar2": false }, //ESLint支持使用第三方插件 //在使用插件之前,你必须使用npm安装它 //全局安装的ESLint只能使用全局安装的插件 //本地安装的ESLint不仅可以使用本地安装的插件还可以使用全局安装的插件 //plugin与extend的区别:extend提供的是eslint现有规则的一系列预设 //而plugin则提供了除预设之外的自定义规则,当你在eslint的规则里找不到合适的的时候 //就可以借用插件来实现了 "plugins": [ // "eslint-plugin-airbnb", //插件名称可以省略eslint-plugin-前缀 // "react" ], //具体规则配置 //off或0--关闭规则 //warn或1--开启规则,警告级别(不会导致程序退出) //error或2--开启规则,错误级别(当被触发的时候,程序会退出) "rules": { "eqeqeq": "warn", //你也可以使用对应的数字定义规则严重程度 "curly": 2, //如果某条规则有额外的选项,你可以使用数组字面量指定它们 //选项可以是字符串,也可以是对象 "quotes": ["error", "double"], "one-var": ["error", { "var": "always", "let": "never", "const": "never" }], //配置插件提供的自定义规则的时候,格式为:不带前缀插件名/规则ID // "react/curly": "error" }, //ESLint支持在配置文件添加共享设置 //你可以添加settings对象到配置文件,它将提供给每一个将被执行的规则 //如果你想添加的自定义规则而且使它们可以访问到相同的信息,这将会很有用,并且很容易配置 "settings": { "sharedData": "Hello" }, //Eslint检测配置文件步骤: //1.在要检测的文件同一目录里寻找.eslintrc.*和package.json //2.紧接着在父级目录里寻找,一直到文件系统的根目录 //3.如果在前两步发现有root:true的配置,停止在父级目录中寻找.eslintrc //4.如果以上步骤都没有找到,则回退到用户主目录~/.eslintrc中自定义的默认配置 "root": true, //extends属性值可以是一个字符串或字符串数组 //数组中每个配置项继承它前面的配置 //可选的配置项如下 //1.字符串eslint:recommended,该配置项启用一系列核心规则,这些规则报告一些常见问题,即在(规则页面)中打勾的规则 //2.一个可以输出配置对象的可共享配置包,如eslint-config-standard //可共享配置包是一个导出配置对象的简单的npm包,包名称以eslint-config-开头,使用前要安装 //extends属性值可以省略包名的前缀eslint-config- //3.一个输出配置规则的插件包,如eslint-plugin-react //一些插件也可以输出一个或多个命名的配置 //extends属性值为,plugin:包名/配置名称 //4.一个指向配置文件的相对路径或绝对路径 //5.字符串eslint:all,启用当前安装的ESLint中所有的核心规则 //该配置不推荐在产品中使用,因为它随着ESLint版本进行更改。使用的话,请自己承担风险 "extends": [ "standard" ] } 复制代码
增加.eslintignore文件
/dist/ /node_modules/ /*.js 复制代码
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- 合格的配置中心应有的素养
- 一个合格的Webpack4配置工程师素养:第二部分
- 一个合格的Webpack4配置工程师素养:第一部分
- 代码整洁之道——程序员的职业素养
- 成为一名安全资深工程师应该具备怎样的素养!
- 《代码整洁之道》和《程序员的职业素养》读书笔记
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。