安装
全局不推荐
npm install webpack webpack-cli -g//webpack-cli 可以帮助我们在命令行⾥使⽤npx ,webpack等相关指令 webpack -v
局部安装 项⽬内安装
npm install webpack webpack-cli --save-dev //-D webpack -v //command not found 默认在全局环境中查找 npx webpack -v// npx帮助我们在项⽬目中的node_modules⾥查找webpack
安装指定版本
npm info webpack//查看webpack的历史发布信息 npm install webpack@x.xx webpack-cli -D
webpack 配置文件
webpack有默认的配置文件,叫webpack.config.js,我们可以对这个文件进行修改,进行个性化配置,也可以不使用默认的配置文件。
默认的配置文件:webpack.config.js
npx webpack //执行命令后,webpack会找到默认的配置文件,并使用执行
不使用默认的配置文件: webpackconfig.js
npx webpack --config webpackconfig.js //指定webpack使用webpackconfig.js文件来作为 配置文件并执行
Webpack 的核⼼心概念
entry
指定打包⼊⼝口文件
entry:{ main: './src/index.js' } ===== entry:"./src/index.js"
output
打包后的文件位置
output: { publicPath:"xxx", filename: "bundle.js", // 必须是绝对路路径 path: path.resolve(__dirname, "dist") }
loader
webpack是模块打包工具,默认只知道如何处理js模块,⽽模块不仅仅是js,还可以是css,图片或者其他格式 ,那么其他格式的模块处理,和处理方式就需要loader了。
当webpack处理到不认识的模块时,需要在webpack中的module处进行配置,当检测到是什么格式的模块,使用什么loader来处理。
module: { rules: [ { test: /.xxx$/, loader: 'xxx-loader', options: { ... } } ] },
常用loader
处理静态资源:
file-loader:处理静态资源模块。
原理是把打包⼊⼝口中识别出的资源模块,移动到输出⽬目录,并且返回一个地址名称。所以我们什什么时候用file-loader呢?场景:就是当我们需要模块,仅仅是从源代码挪移到打包⽬目录,就可以使用file-loader来处理,txt,svg,csv,excel,图片资源啦等等。
npm install file-loader -D
module: { rules: [ { test: /.(png|jpe?g|gif)$/, loader: 'file-loader', options: { name: "[name]_[hash].[ext]",//[name]⽼资源模块的名称,[ext]老资源模块的后缀 outputPath: 'img/'//打包后的存放位置 } } ] },
url-loader
可以处理file-loader所有的事情,但是遇到jpg格式的模块,会把该图片转换成base64格式字符串,并打包到js里。对⼩小体积的图片⽐比较合适,⼤大图片不合适。
module: { rules: [ { test: /.(png|jpe?g|gif)$/, loader: "url-loader", options: { name: "[name]_[hash].[ext]", outputPath: "images/", //⼩小于2048,才转换成base64 limit: 2048 } } ] },
处理css
style-loader css-loader
css-loader 分析css模块之间的关系,并合成一个css;把css-loader⽣生成的内容,以style挂载到⻚页面的heade部分。
npm install style-loader css-loader -D
module: { rules: [ { test: /.css$/, use: ["style-loader", "css-loader"] } ] },
sass-load
sass-load 把sass语法转换成css ,依赖node-sass模块
npm install sass-loader node-sass -D
module: { rules: [ { test: /.scss$/, use: ["style-loader", "css-loader", "sass-loader"] } ] },
postcss-loader
样式⾃自动添加前缀
npm i -D postcss-loader
module: { rules: [ { test: /.css$/, use: ["style-loader", "css-loader","postcss-loader"] } ] },
安装autoprefixer
npm i autoprefixer -D
新建postcss.config.js
module.exports = { plugins: [require("autoprefixer")] };
处理es6
babel-loader
babel-loader是webpack 与 babel的通信桥梁,不会做把es6转成es5的工作,这部分工作需要用到 @babel/preset-env来做;@babel/preset-env里包含了了es6转es5的转换规则。
npm i babel-loader @babel/core @babel/preset-env -D
通过上面的几步 还不够,Promise等一些还有转换过来,需要用@babel/plugin-transform-runtime,把es的新特 性都装进来,来弥补低版本浏览器器中缺失的特性
npm install --save-dev @babel/plugin-transform-runtime npm install --save @babel/runtime
module.exports = { module: { rules: [ { test: /.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { plugins: [ [ "@babel/plugin-transform-runtime", { "absoluteRuntime": false, "corejs": 2, "helpers": true, "regenerator": true, "useESModules": false } ] ] } } ] } }
如果觉着options的东西太多了,写这里不太合适,可以新建一个.babelrc文件。把options部分移⼊到该文件中。
//.babelrc { "plugins": [ [ "@babel/plugin-transform-runtime", { "absoluteRuntime": false, "corejs": 2, "helpers": true, "regenerator": true, "useESModules": false } ] ] } //webpack.config.js { test: /.js$/, exclude: /node_modules/, loader: "babel-loader" }
配置React打包环境,安装babel与react转换的插件。
npm install --save-dev @babel/preset-react
在babelrc文件里添加:
//.babelrc { "plugins": [ [ "@babel/plugin-transform-runtime", { "absoluteRuntime": false, "corejs": 2, "helpers": true, "regenerator": true, "useESModules": false } ], "@babel/preset-react" ] }
plugins
plugin 是 wepback 的支柱功能。插件目的在于解决 loader无法实现的其他事,由于loader仅在每个文件的基础上执行转换,而插件(plugins) 常用于(但不限于)在打包模块的 “compilation” 和 “chunk” 生命周期执行操作和自定义功能。想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。
多数插件可以通过选项(option)自定义。
常用 plugins
HtmlWebpackPlugin
html-webpack-plugin会在打包结束后,自动⽣成一个html文件,并把打包生成的js模块引⼊到该html 中。
npm install --save-dev html-webpack-plugin
clean-webpack-plugin
清除打包生成的冗余重复文件
mini-css-extract-plugin
会在打包结束后,自动生成一个css文件,并把打包生成的css模块引⼊到html 中。
module.exports = { module: { rules: [ { test: /.css$/, use: [ { loader: MiniCssExtractPlugin.loader },//用MiniCssExtractPlugin,这里就不是style-loade了 'css-loader', 'postcss-loader' ] } ... ] }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: '模板', template: './index.html' }), new MiniCssExtractPlugin({ filename: '[name].css' }), ], ... }
WebpackDevServer
提升开发效率的利器 每次改完代码都需要重新打包一次,打开浏览器,刷新一次,很麻烦 我们可以安装使用webpackdevserver来改善这块的体验。
npm install webpack-dev-server -D
module.exports = { ... devServer: { contentBase: "./dist", open: true, port: 8081 }, }
启动服务后,会发现dist⽬目录没有了了,这是因为devServer把打包后的模块不会放在dist⽬目录下,⽽是放 到内存中,从⽽提升速度。
开发期间,webpack可以配置proxy搞定跨域,上线后我们使用nginx转发。
module.exports = { ... devServer: { ... proxy: { '/api': { target: 'http://localhost:9092'//所有以/api开头的请求都转发到http://localhost:9092 } } }, }
Hot Module Replacement (HMR:热模块替换)
启动hmr
const webpack = require("webpack"); ... module.exports = { ... plugins: [ new webpack.HotModuleReplacementPlugin() ], devServer: { ... hot:true, hotOnly:true,//即便便HMR不⽣生效,浏览器器也不⾃自动刷新,就开启hotOnly }, }
这样至少css变化会引起热更新,但是js不会,要想使js热更新,还需要使用module.hot.accept来观察模块更新 从⽽更新。
//index.js if (module.hot) { module.hot.accept("./xxx", function() { ... }); }
sourceMap
源代码与打包后的代码的映射关系,
开发环境推荐:devtool:"cheap-module-eval-source-map"线上环境可以不开启:如果要看到一些错误信息,推荐devtool:"cheap-module-source-map"
devtool参数说明:eval:速度最快
cheap:较快,不用管列的报错
module:第三方模块
cheap:较快,不用管列的报错
module:第三方模块
module.exports = { mode: 'development', devtool: "cheap-module-eval-source-map", }
webpack.config.js
const path = require('path') const HtmlWebpackPlugin = require('html-webpack-plugin'); const { CleanWebpackPlugin } = require('clean-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports = { entry: "./index.js", output: { // filename: 'pack.js', path: path.resolve(__dirname, './dist') }, module: { rules: [ { test: /.(png|jpe?g|gif)$/, loader: "url-loader", options: { name: "[name]_[hash].[ext]", outputPath: "images/", //⼩小于2048,才转换成base64 limit: 2048 } }, { test: /.css$/, use: [ { loader: MiniCssExtractPlugin.loader }, 'css-loader', 'postcss-loader' ] }, { test: /.scss$/, use: ['style-loader', 'css-loader', 'sass-loader'] }, { test: /.js$/, exclude: /node_modules/, loader: 'babel-loader', options: { plugins: [ [ "@babel/plugin-transform-runtime", { "absoluteRuntime": false, "corejs": 2, "helpers": true, "regenerator": true, "useESModules": false } ] ] } } ] }, plugins: [ new CleanWebpackPlugin(), new HtmlWebpackPlugin({ title: '模板', template: './index.html' }), new MiniCssExtractPlugin({ filename: '[name].css' }), ], mode: 'development', devtool: "cheap-module-eval-source-map", devServer: { contentBase: "./dist", open: true, port: 8081, proxy: { '/api': { target: 'http://localhost:9092' } } }, }