装置
- 全局装置
webpack
和webpack-cli
,是为了能够应用webpack
这个命令,不然你应用不了命令,当然手动增加环境变量也是能够的,部分装置是为了锁定版本,不便开发对立版本号,这里是应用了指定版本号的,也是踩了坑的,版本号不同,配置大同小异,然而,外面一个变动,你不晓得,出错了就有你好查的了。 自己在做开发的时候,遇到的最多的就是版本号的坑。基本上
webpack
版本号是多少,其余的关联包,根本都要在肯定范畴内,超出了范畴,就等着一堆报错吧,自己用的这个版本是本人踩过确定可用的。npm i webpack@4.46 webpack-cli-3.3.12 -gnpm i webpack@4.46 webpack-cli-3.3.12 -D
- 如果不想批改一次内容,就打包一次看成果,还能够装置上面和这个包
- 而后只须要运行,
npx webpack-dev-server
或者npx webpack serve
,而后咱们再改变代码,就能立即在浏览器中看到对应的成果了 npx webpack-dev-server
不好记还长,那么在package.json
的scripts中配置个dev启动命令吧:"dev": "webpack-dev-server"
或者"dev": "webpack serve"
该形式就是用来实时预览的,不会打包,只会在内存中虚构打包,让你看到成果,须要打包的话还是要应用
webpack
命令打包。npm i webpack-dev-server@3.11.0
package.json文件中的配置
// 更新于2022/02/22{ "name": "webpack1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "dev": "webpack-dev-server", "build": "webpack --config webpack.config.js", "prod": "webpack --config webpack.prod.config.js" }, "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.11.6", "@babel/polyfill": "^7.11.5", "@babel/preset-env": "^7.11.5", "add-asset-html-webpack-plugin": "^5.0.1", "babel-eslint": "^10.1.0", "babel-loader": "^8.1.0", "core-js": "^3.21.1", "css-loader": "^4.3.0", "eslint": "^7.11.0", "eslint-config-airbnb-base": "^15.0.0", "eslint-loader": "^4.0.2", "eslint-plugin-import": "^2.25.4", "file-loader": "^6.1.0", "html-loader": "^1.3.2", "html-webpack-plugin": "^4.5.0", "less": "^4.1.2", "less-loader": "^6.0.0", "mini-css-extract-plugin": "^1.0.0", "optimize-css-assets-webpack-plugin": "^5.0.4", "postcss": "^8.1.1", "postcss-loader": "^4.0.4", "postcss-preset-env": "^7.4.1", "style-loader": "^2.0.0", "url-loader": "^4.1.0", "webpack": "^4.46.0", "webpack-cli": "^3.3.12", "webpack-dev-server": "^3.11.0" }, "dependencies": { "@babel/polyfill": "^7.11.5", "core-js": "^3.21.1", "jquery": "^3.6.0" }, "browserslist": { "development": [ ">0.2%", "not dead", "not op_mini all" ], "production": [ ">0.2%", "not dead", "not op_mini all" ] }, "eslintConfig": { "extends": "airbnb-base", "parser": "babel-eslint" }}
webpack.config.js配置
配置中的五个外围点
Entry(入口)
- Entry 批示 Webpack 以哪个文件为入口终点开始打包,剖析构建外部依赖图
Output(输入)
- Output 批示 Webpack 打包后资源的 bundles 输入到哪里去,以及如何命名
Module
- Module中的Loader 让 Webpack 可能去解决那些非JS文件(webpack自身只了解JS,还有JSON)
Plugins(插件)
- Plugins 能够用于执行范畴更广的工作,插件的范畴包含从打包优化和压缩,始终到从新定义环境中的变量等
Mode(模式)
Mode 批示 Webpack 应用相应模式的配置
- development
- production
配置文件具体代码
/* webpack.config.js: webpack的配置文件 作用:批示webpack干哪些活,即当你运行webpack指令时,会加载外面的配置 所有构建工具都是基于NodeJS平台运行的, 所以模块化采纳的都是commonjs 开发环境配置*/// 应用resolve用来拼接绝对路径的办法const {resolve} = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin');const MiniCssExtractPlugin = require('mini-css-extract-plugin');const OptimizeCssAssetsWebpackPlugin = require('optimize-css-assets-webpack-plugin');const webpack = require('webpack')const AddAssetHtmlWebpackPlugin = require('add-asset-html-webpack-plugin')// 设置nodejs环境变量process.env.NODE_ENV = 'development'/* entry: 入口终点 1. string ---> './src/index.js' - 单入口 - 打包造成一个chunk,输入一个bundle文件。 - 此时chunk的名称默认为main 2. array ---> ['./src/index.js','./src/index2.js'] - 多入口 - 所有入口文件最终只会造成一个chunk,输入进来只有一个bundle文件。 - 一般来讲,只有在HMR性能中让html的热更新失效:['./src/index.js','./src/index.html'] 3. object ---> { index: './src/index.js', index2:'./src/index2.js'} - 多入口 - 有几个入口文件就造成几个chunk,输入几个bundle文件,这个也是文件切割的一种模式 - 此时chunk的名称是key - 非凡用法:能够用来把两个打包成一个 { index: ['./src/index.js','./src/add.js', index2:'./src/index2.js' }*/module.exports = { // webpack配置 // 入口 entry: ['./src/index.js','./src/index.html'], // 输入 output: { // 输入文件名 filename: 'js/[name].[hash:10].js', // 输入门路 path: resolve(__dirname,'dist'), // 所有资源引入的公共门路前缀:'./img/bg.png' // publicPath: '/', // 非入口chunk的名称 // chunkFilename: '', // 整个库向外裸露的变量名,个别只有联合dll才应用 // library: '[name]', // 变量名增加到哪个上 // libraryTarget: 'window' // libraryTarget: 'browser' }, // loader的配置 module: { // 具体loader配置 rules: [ // JS的语法查看:eslint eslint-loader // 除了要下面的两个,咱们还须要下载个规定,规定的意思是依照下面规定查看js的谬误 // airbnb: eslint-config-airbnb-base eslint-plugin-import // 除此之外还要在package.json中配置 eslintConfig { test: /\.js$/, // 须要留神的是咱们只须要查看本人的源代码,第三方的库是不必查看的 exclude: /node_modules|css/, // 只查看src文件夹上面的文件 // include: resolve(__dirname, 'src'), // 优先执行,比方eslint和babel这里两个,eslint就要先执行,不然就非常容易报错 enforce: 'pre', // 延后执行,不写是两头执行 // enforce: 'post', loader: 'eslint-loader', options: { // 开启eslint主动修复eslint的谬误 fix: true } }, { // 以下loader只会匹配一个,防止每个文件都过了一遍loader,次要是生产环境的打包速度优化 // 留神:不能有两个配置解决批准类型文件,比方babel-loader和eslint-loader都要解决js,那样只会执行一个,所以把其中一个还间接放在rules中 oneOf: [ // css文件解决 { // 正则匹配文件 test: /\.css$/, // 指定须要应用的loader // use数组中loader执行程序是,从右到左,从下到上 // use外面能够是间接的字符串,也能够是对象,应用对象通常使咱们要批改外面的配置 use: [ // 创立一个style标签,将js中的款式资源插入到进去,增加到head中失效 // 'style-loader', // 和下面style-loader不同的是,应用插件,能够把css独自打包进去 { loader: MiniCssExtractPlugin.loader, options: { publicPath: '../' } }, // 将css文件,变成commonjs模块,加载到js中。外面的内容是款式字符串 'css-loader', // css兼容性解决,须要用到postcss,须要下载postcss-loader和postcss-preset-env { loader: 'postcss-loader', options: { postcssOptions: { ident: 'postcss', plugins: () => { require('postcss-preset-env')() } } } } ] }, // less文件解决 { // 正则匹配文件 test: /\.less$/, use: [ { loader: MiniCssExtractPlugin.loader, options: { publicPath: '../' } }, 'css-loader', // css兼容性解决,须要用到postcss,须要下载postcss-loader和postcss-preset-env { loader: 'postcss-loader', options: { postcssOptions: { ident: 'postcss', plugins: () => { require('postcss-preset-env')() } } } }, 'less-loader' ] }, // 图片解决 { // 正则匹配文件 test: /\.(jpg|png|gif|jpeg)$/, // 因为url-loader依赖于file-loader,所以要下载两个loader loader: 'url-loader', options: { // 图片小于8kb,会被转换成base64, // 长处:缩小申请数量,加重服务器压力 // 毛病:图片提及会更大,文件申请诉速度会更慢 limit: 8092, // 手动设置图片的名字(能够不设置):name(图片原来的名字),hash(hash值,10代表去前10位),ext(图片原来的格局) name: '[name].[hash:10].[ext]', // 因为文件的引入是es6语法,然而webpack是遵循commonjs规定的,所以想要html文件中想要应用图片,必须把es6关掉。这是给上面的html中图片解决用的 esModule: false, // 指定打包后文件输入地位 outputPath: 'assets/imgs' } }, // html中图片解决 { // 正则匹配文件 test: /\.html$/, loader: 'html-loader', }, // 解决其余类型文件 { // 排除css,js,html等文件,应用这个打包形式 exclude: /\.(html|js|css|less|png|jpg|jpeg|gif)/, loader: 'file-loader', options: { name: '[name].[hash:10].[ext]', outputPath: 'assets' } }, // JS的兼容解决,即ES6转ES5:babel-loader, @babel/core, @babel/preset-env // @babel/preset-env只做根本语法的转换 // @babel/polyfill做全类型转换,然而有一点,咱们只须要做局部的转换,全副引入,体积就会太大了 // 按需加载:应用core.js { test: /\.js$/, exclude: /node_modules|css/, loader: 'babel-loader', options: { // 预设:批示babel做怎么样的兼容解决 presets: [ [ '@babel/preset-env', { // 按需加载 useBuiltIns: 'usage', // 指定core-js版本 corejs: { version: 3 }, // 指定兼容性做到浏览器的那个版本 targets: { chrome: '60', firefox: '50', ie: '9', safari: '10', edge: '15' } } ] ], // 开启babel缓存 // 第二次构建时,会读取之前的缓存 // 次要是防止多个js的状况下,只批改其中一个或一部分,导致所有的js都要再构建一次 cacheDirectory:true } } ] }, ] }, // plugins的配置 plugins: [ // 解决html // html-webpack-plugin // 性能:默认会创立一个空的HTML文件,主动引入打包好的所有资源 new HtmlWebpackPlugin({ // 复制'./src/index.html' 文件到打包好的文件中,并引入所有资源 template: './src/index.html', // 压缩html代码 // minify: { // // 移除空格 // collapseWhitespace: true, // // 移除正文 // removeComments: true // } }), // css独自提出来 new MiniCssExtractPlugin({ // 应用contenthash,能够让css应用缓存,只有当css批改才会从新打包,而hash和chunkhash都不行,因为hash每次打包都不一样,而chunkhash不行是因为css是在js中引入的,所以每次也都是变动的 filename: 'css/built.[contenthash:10].css' }), // 压缩css // new OptimizeCssAssetsWebpackPlugin() // 通知webpack哪些库不参加打包,同时应用时的名称也须要扭转 new webpack.DllReferencePlugin({ manifest: resolve(__dirname, 'dll/manifest.json') }), // 将某个文件打包输入进来,并在html中主动引入改文件(给dll性能应用的) new AddAssetHtmlWebpackPlugin({ filepath: resolve(__dirname, 'dll/jquery.js') }) ], // 模式 mode: 'development', // 开发模式 // mode: 'production', // 生产模式,该模式会主动压缩代码 // 开发服务器 devServer: 用来自动化的编译,关上浏览器,主动刷新浏览器 // 自会在内存中编译打包,不会有任何的输入 devServer: { // 我的项目构建后门路 contentBase: resolve(__dirname, 'dist'), // 是否在首次编译后主动关上浏览器 open: true, // 启动gzip压缩 compress: true, // 地址 host: '127.0.0.1', // 端口好 port: 8527, /* 开启HMR性能,HMR:hot module replace(热加载) * css在hot: true默认开启HMR * js默认没有开启HMR - 入口JS文件不须要开启HMR,所以须要监听的是其余模块 - 其余JS文件的监听形式是在入口JS外面写一个监听代码 if(module.hot) { // 办法会监听add.js文件,一旦发生变化,其余模块会从新打包构建 // 而后执行前面的回调函数 module.hot.accept('./asstes/js/add.js',function() { add() }) } * html默认没有开启HMR,而且同时会导致html的热更新生效,复原热更新须要批改entry --> entry: ['./src/index.js','./src/index.html'],然而还是没有HMR,html也不须要HMR,尤其是单页面只有一个index.html的状况下 - 额定说:热更新和热加载不一样: - 热更新:文件内动改变后,整个页面刷新,不保留任何状态(比方输出过内容的Input表单),相当于webpack帮你摁了F5刷新 - 热加载:文件改变后,以最小的代价扭转被扭转的区域。尽可能保留改变文件前的状态(对input输出内容后,批改其余标签的代码) */ hot: true, // 监督contentBase目录下的所有文件,一旦文件变动就会reload watchContentBase: true, // 监督文件的配置 watchOptions: { // 疏忽要监督的文件 ignored: /node_modules/ }, // 不要显示启动服务器日志信息 clientLogLevel: 'none', // 除了一些根本的启动信息外,其余内容都不要显示 quiet: true, // 如果出错了,不要全屏提醒 overlay: false, // 服务器代理:解决开发环境跨域问题 proxy: { // 一旦devServer(8527)服务器接管到 /api/xxx 的申请,就会转发到另个服务器上(3000) '/api': { target: 'http://localhost:3000', // 发送申请时,申请门路重写,将 /api/xxx --> /xxx (去掉了 /api) pathRewrite: { '^/api': '' } } } }, // 提供源代码到构建后代码映射技术 devtool: 'eval-source-map', /* 文件离开打包的第二种模式 能够将node_modules中代码独自打包成一个chunk最终输入,入口文件独自一个chunk 下面的是单入口文件,该性能还会主动剖析多入口chunk中,有没有公共的文件,如果有会打包成一个独自的chunk */ // optimization: { // splitChunks: { // chunks: 'all' // } // }, // 用来解决咱们不须要本人打包,而是通过cdn引入的一些文件 // externals: { // // 回绝某个文件被打包 // jquery: 'jQuery' // } // 解析模块的规定 resolve: { // 配置解析模块门路的别名,长处是简写门路,毛病是没有门路提醒 alias: { $css: resolve(__dirname, 'src/css') }, // 配置省略文件门路的后缀名 // extensions: ['js','json','jsx'], // 通知webpack解析模块是去找哪个目录 modules: [resolve(__dirname,'../node_modules'),'node_modules'] }}/* tree shaking: 必须在production模式下,另外一个条件是,须要应用ES6的模块化,在这两个条件满足的状况下,会主动去除无用代码,较少代码体积 PS: 有的版本的treeshaking有点问题,会把css当成无用代码干掉,这个时候须要在package.json中增加点配置 - "sideEffects": ["*.css","*.less"] 意思是避开css和less文件进行tree shaking - "sideEffects": false 意思是所有文件都能够进行tree shaking*//* source-map: 提供源代码到构建后代码映射技术(如果构建后代码出错了,通过映射能够追踪源代码的谬误) source-map: 内部 - 错误代码精确信息 和 源代码的谬误地位 inline-source-map: 内联 - 只生成一个内联source-map - 错误代码精确信息 和 源代码的谬误地位 hidden-source-map: 内部 - 错误代码的谬误起因,然而没有提醒谬误地位 - 不追踪源代码的谬误,只能提醒到构建后代码的谬误地位 eval-source-map: 内联 - 每一个文件都生成对应的source-map,都在eval - 错误代码精确信息 和 源代码的谬误地位 nosource-source-map: 内部 - 错误代码精确信息,然而没有人任何源代码信息 cheap-source-map: 内部 - 错误代码精确信息 和 源代码的谬误地位 - 只能准确到行,然而不能准确到行的哪一块出错 cheap-module-source-map: 内部 - 错误代码精确信息 和 源代码的谬误地位 - module会将loader的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 生产环境:源代码要不要暗藏,调试要不要敌对 - 内联会让体积变大,所以生产环境不要用内联 - nosource-source-map: 全副代码暗藏 - hidden-source-map: 只暗藏源代码,会提醒构建后代码错误信息 - 个别生产环境用 source-map*/