webpack是一个模块打包器,可以根据入口文件,随着依赖关系将所有文件打包成js文件。
首先需要node环境,百度一下自己安装
webpack官网地址:https://www.webpackjs.com
首先,建立一个文件,叫webpack1(不能叫webpack,否则初始化报错)
初始化:
npm init -y
初始化之后,文件夹中会出现一个package.json文件
之后安装webpack
npm i -D webpack
webpack4还需要安装一个webpack-cli
npm i -D webpack-cli
之后在根目录下创建一个src文件夹,里面放的是源码,里面放一个index.js,是入口文件;
在根目录建一个dist文件,用来盛放打包后的文件,dist文件夹中再放一个index.html文件;
再在跟目录下创建一个webpack.config.js文件,当做webpack的配置文件
在src/index.js中随便写点代码:
import _ from 'lodash'; import "./style/index.css";//loader=>css-loader module style-loader import "./style/a.scss"; function createDomElement(){ let dom = document.createElement('div'); dom.innerHTML=_.join(["aicoder.com","好!","线下实习"],""); // dom.className="box"; dom.classList.add("box"); return dom; } let divDom = createDomElement(); document.body.appendChild(divDom);
在webpack.config.js中作出简单配置:
const path = require("path"); module.exports={ entry:"./src/index.js",//入口文件 mode:"development",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { //告诉webpack,当import,require遇到.css文件时,用css-loader、style-loader处理一下 test: /.(sc|c|sa)ss$/,//scss,css,sass use: ["style-loader","css-loader","sass-loader"],//loader的使用数据是从右向左的 } ] } }
在dist/index.html中引入打包生成的main.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script src="./main.js"></script>
</body>
</html>
当然我们还在src/style/中加了index.css和a.sass文件,
如果想让webpack打包js之外的文件,需要安装对应的loader
css需要css-loader(用来解析css文件)、style-loader(用来将打包好的css文件用style标签引入)
scss文件需要 sass-loader 和 node-sass
一口气安装了:
npm i -D css-loader style-loader sass-loader node-sass
之后执行npx webpack
dist文件中就会出现打包好的main.js
然后就可以打开dist/index.html看一下效果。
如果我们想执行自己的自定义命令来让webpack打包,我们可以在package.json的script中配置一下命令,如:
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build":"npx webpack -c webpack.config.js" },
之后我们执行 npm run build就可以让webpack打包了
上面的-c webpack.config.js指的是 webpack是根据哪个文件的配置打包的
----------------------------------------------------------------------------------------------------------------------------
由于webpack是将所有的依赖文件打包成一个文件,当我们想调试css样式时,我们很难在控制台看到某一句代码是来自哪个源文件的,所以我们需要开启sourceMap,
在webpack.config.js中国这样配置:
module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: ["style-loader",{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"sass-loader", options:{ sourceMap:true } }], } ] }
然后执行npm run build 在控制台查看css样式,就可以清晰的看到某个样式,是来自哪一个文件(index.css还是a.scss一目了然)
------------------------------------------------------------------------------------------------------------
另外我们一般还会用到postcss 以及 autuoprefixer
postcss 可以对css进行预处理 校验css 以及自动添加前缀 可以提前使用css的一些新特性
首先安装 (我们此处只用了 自动添加前缀的插件 所以额外安装了autoprefixer)
npm i -D postcss-loader
npm install --save-dev autoprefixer
在webpack.config.js中添加对应配置:
module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: ["style-loader",{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了)
] } },{ loader:"sass-loader", options:{ sourceMap:true } }], } ] }
----------------------------------------------------------------------------------------------------
将css文件单独抽离出来
npm install --save-dev mini-css-extract-plugin
一般我们都是在生产环境将css文件单独抽离出来的,所以我们在根目录中创建webpack.product.config.js文件,用来配置生产环境下的webpack配置,将上面的webpack.config.js中的配置复制一份过来,做以下改变:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); module.exports={ entry:"./src/index.js",//入口文件 mode:"production",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: [ MiniCssExtractPlugin.loader,{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], } ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename:'[name].[hash].css', chunkFilename:'[id].[hash].css', }) ], }
执行如下命令:
npx webpack --config webpack.product.config.js
就可以用这个配置文件打包了
当然,如果我们需要多次打包 这样输入命令显得有点复杂,我们可以在package.json中的script中增加一个脚本命令:
"dist": "npx webpack --config webpack.product.config.js"
之后,运行npm run dist与上述命令等效
----------------------------------------------------------------------------------------------------------------------------------
css压缩:(生产环境才能用到)
安装这个插件
npm install optimize-css-assets-webpack-plugin --save-dev
在webpack.product.config.js配置:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); module.exports={ entry:"./src/index.js",//入口文件 mode:"production",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: [ MiniCssExtractPlugin.loader,{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], } ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename:'[name].css', chunkFilename:'[id].css', }) ], optimization:{ minimizer:[new OptimizeCSSAssetsPlutin({})] } }
之后执行 npm run dist打包 即可压缩css代码
-------------------------------------------------------------------
js压缩:(生产环境用)
npm i -D uglifyjs-webpack-plugin
在webpack.product.config.js中加入配置:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); module.exports={ entry:"./src/index.js",//入口文件 mode:"production",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: [ MiniCssExtractPlugin.loader,{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], }, // { // test: /.js$/, // loader: 'babel-loader', // exclude: /node_modules/, // } ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename:'[name].css', chunkFilename:'[id].css', }) ], optimization:{ minimizer:[ new UglifyJsPlugin({ cache: true, parallel: true, /** * sourceMap 和 devtool: 'inline-source-map', 冲突 */ sourceMap: false, // set to true if you want JS source maps, /** * extractComments 导出备注 */ extractComments: 'all' }), new OptimizeCSSAssetsPlutin({}) ] } }
然后执行npm run dist 就行
----------------------------------------------------------------------------------
将es6转化转义成es5
安装:
npm i -D babel-loader babel-core babel-preset-env
在根目录新建一个.babelrc文件
配置上:
{ "presets": ["@babel/env"] }
在webpack.product.config.js中配置:
rules: [ { test: /.js$/, loader: 'babel-loader', exclude: /node_modules/ } ]
--------------------------------------------------------------------------
如何将每次打包的js和css文件 自动引入到html文件中:
npm install html-webpack-plugin -D
在config.js中配置:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports={ entry:"./src/index.js",//入口文件 mode:"production",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.[hash].js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: [ MiniCssExtractPlugin.loader,{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], }, { test: /.js$/, loader: 'babel-loader', exclude: /node_modules/ } ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename:'[name][hash].css', chunkFilename:'[id][hash].css', }), new HtmlWebpackPlugin({ title:"webpack 温习",//默认值webpack App filename:"main.html",//默认值index.html 是最终生成的文件名字 template:path.resolve(__dirname,"src/index.html"), minify:{ collapseWhitespace:true,//是否去空白 removeComments:true,//是否移除注释 removeAttributeQuotes:true,//移除属性的引号 } }) ], optimization:{ minimizer:[ new UglifyJsPlugin({ cache: true, parallel: true, /** * sourceMap 和 devtool: 'inline-source-map', 冲突 */ sourceMap: false, // set to true if you want JS source maps, /** * extractComments 导出备注 */ extractComments: 'all' }), new OptimizeCSSAssetsPlutin({}) ] } }
当然,需要在src下简历一个index.html模板
然后,执行npm run dist 即可
-----------------------------------------------------------------------
清理dist目录
每次打包 都会生成一些新的打包文件,从而之前的没用的打包文件也会保留下来,很不爽,所以我们需要一个自动清理dist目录的插件
npm install clean-webpack-plugin --save-dev
在config.js中配置:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports={ entry:"./src/index.js",//入口文件 mode:"production",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.[hash].js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: [ MiniCssExtractPlugin.loader,{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], }, { test: /.js$/, loader: 'babel-loader', exclude: /node_modules/ } ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename:'[name][hash].css', chunkFilename:'[id][hash].css', }), new HtmlWebpackPlugin({ title:"webpack 温习",//默认值webpack App filename:"main.html",//默认值index.html 是最终生成的文件名字 template:path.resolve(__dirname,"src/index.html"), minify:{ collapseWhitespace:true,//是否去空白 removeComments:true,//是否移除注释 removeAttributeQuotes:true,//移除属性的引号 } }), new CleanWebpackPlugin(),//清理构建文件夹 ], optimization:{ minimizer:[ new UglifyJsPlugin({ cache: true, parallel: true, /** * sourceMap 和 devtool: 'inline-source-map', 冲突 */ sourceMap: false, // set to true if you want JS source maps, /** * extractComments 导出备注 */ extractComments: 'all' }), new OptimizeCSSAssetsPlutin({}) ] } }
然后再次构建,dist目录会被清理一下再生成打包文件
--------------------------------------------------------------------------------------------------------
webpack处理图片
首先 打包时处理不了图片这种二进制文件的 路径,我们需要用一个file-loader插件
安装:
npm install --save-dev file-loader
在config.js中配置:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports={ entry:"./src/index.js",//入口文件 mode:"production",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.[hash].js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: [ MiniCssExtractPlugin.loader,{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], }, { test: /.js$/, loader: 'babel-loader', exclude: /node_modules/ }, {//处理图片 路径 test:/.(png|svg|gif|jpg|jpeg)$/, use:[ 'file-loader' ] } ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename:'[name][hash].css', chunkFilename:'[id][hash].css', }), new HtmlWebpackPlugin({ title:"webpack 温习",//默认值webpack App filename:"main.html",//默认值index.html 是最终生成的文件名字 template:path.resolve(__dirname,"src/index.html"), minify:{ collapseWhitespace:true,//是否去空白 removeComments:true,//是否移除注释 removeAttributeQuotes:true,//移除属性的引号 } }), new CleanWebpackPlugin(),//清理构建文件夹 ], optimization:{ minimizer:[ new UglifyJsPlugin({ cache: true, parallel: true, /** * sourceMap 和 devtool: 'inline-source-map', 冲突 */ sourceMap: false, // set to true if you want JS source maps, /** * extractComments 导出备注 */ extractComments: 'all' }), new OptimizeCSSAssetsPlutin({}) ] } }
这样,打包时,图片路径就不会报错了
打包后,dist中会多出打包后的图片文件
那么,如果我们想将图片进行优化呢?
我们需要借助一个插件:
npm install image-webpack-loader --save-dev
config.js配置:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports={ entry:"./src/index.js",//入口文件 mode:"production",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.[hash].js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: [ MiniCssExtractPlugin.loader,{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], }, { test: /.js$/, loader: 'babel-loader', exclude: /node_modules/ }, {//处理图片 路径 test:/.(png|svg|gif|jpg|jpeg)$/, include:[path.resolve(__dirname,'src/')], use:[ 'file-loader', { loader: 'image-webpack-loader', }, ] } ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename:'[name][hash].css', chunkFilename:'[id][hash].css', }), new HtmlWebpackPlugin({ title:"webpack 温习",//默认值webpack App filename:"main.html",//默认值index.html 是最终生成的文件名字 template:path.resolve(__dirname,"src/index.html"), minify:{ collapseWhitespace:true,//是否去空白 removeComments:true,//是否移除注释 removeAttributeQuotes:true,//移除属性的引号 } }), new CleanWebpackPlugin(),//清理构建文件夹 ], optimization:{ minimizer:[ new UglifyJsPlugin({ cache: true, parallel: true, /** * sourceMap 和 devtool: 'inline-source-map', 冲突 */ sourceMap: false, // set to true if you want JS source maps, /** * extractComments 导出备注 */ extractComments: 'all' }), new OptimizeCSSAssetsPlutin({}) ] } }
--------------------------------------------------------------------------------
将图片进一步优化处理 成base64
将图片转化成base64的dataurl的形式,提高页面性能
npm install --save-dev url-loader
我们只需要将file-loader变成url-loader即可:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports={ entry:"./src/index.js",//入口文件 mode:"production",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.[hash].js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: [ MiniCssExtractPlugin.loader,{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], }, { test: /.js$/, loader: 'babel-loader', exclude: /node_modules/ }, {//处理图片 路径 test:/.(png|svg|gif|jpg|jpeg)$/, include:[path.resolve(__dirname,'src/')], use:[ { loader:'url-loader', options:{//小于10000字节的图片转换成base64格式 limit:10000 } }, { loader: 'image-webpack-loader', }, ] } ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename:'[name][hash].css', chunkFilename:'[id][hash].css', }), new HtmlWebpackPlugin({ title:"webpack 温习",//默认值webpack App filename:"main.html",//默认值index.html 是最终生成的文件名字 template:path.resolve(__dirname,"src/index.html"), minify:{ collapseWhitespace:true,//是否去空白 removeComments:true,//是否移除注释 removeAttributeQuotes:true,//移除属性的引号 } }), new CleanWebpackPlugin(),//清理构建文件夹 ], optimization:{ minimizer:[ new UglifyJsPlugin({ cache: true, parallel: true, /** * sourceMap 和 devtool: 'inline-source-map', 冲突 */ sourceMap: false, // set to true if you want JS source maps, /** * extractComments 导出备注 */ extractComments: 'all' }), new OptimizeCSSAssetsPlutin({}) ] } }
----------------------------------------------------------------------------------
如何将不同环境的webpack配置文件合并,将共同配置共用?
npm install --save-dev webpack-merge
首先,我们需要改变配置文件的结构,之前是webpack.config.js和webpack.product.config.js分别充当 开发和生产环境配置,
现在我们分为webpack.common.js、webpack.dev.js、webpack.prod.js 这三个文件分别写着公共配置、开发环境特有配置、生产环境特有配置
下面写出栅格文件的内容:
webpack.common.js:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports={ entry:"./src/index.js",//入口文件 module: { rules: [ { test: /.js$/, loader: 'babel-loader', exclude: /node_modules/ }, {//处理图片 路径 test:/.(png|svg|gif|jpg|jpeg)$/, include:[path.resolve(__dirname,'src/')], use:[ { loader:'url-loader', options:{//小于10000字节的图片转换成base64格式 limit:10000 } }, { loader: 'image-webpack-loader', }, ] } ] }, plugins: [ new HtmlWebpackPlugin({ title:"webpack 温习",//默认值webpack App filename:"main.html",//默认值index.html 是最终生成的文件名字 template:path.resolve(__dirname,"src/index.html"), minify:{ collapseWhitespace:true,//是否去空白 removeComments:true,//是否移除注释 removeAttributeQuotes:true,//移除属性的引号 } }), new CleanWebpackPlugin(),//清理构建文件夹 ], }
webpack.dev.js:
const path = require("path"); const merge = require('webpack-merge');//引入webpack-merge参数 const common = require('./webpack.common');//将webpack.common.js引入 let devConfig={ mode:"development",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: ["style-loader",{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], } ] } } module.exports=merge(common,devConfig);//第一个参数是基本配置 后面的参数是当前配置
webpack.prod.js:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); const merge = require('webpack-merge');//引入webpack-merge参数 const common = require('./webpack.common');//将webpack.common.js引入 let prodConfig={ mode:"production",//模式是开发环境 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.[hash].js", path:path.resolve(__dirname,"dist") }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: [ MiniCssExtractPlugin.loader,{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], }, { test: /.js$/, loader: 'babel-loader', exclude: /node_modules/ }, ] }, plugins: [ new MiniCssExtractPlugin({ // Options similar to the same options in webpackOptions.output // both options are optional filename:'[name][hash].css', chunkFilename:'[id][hash].css', }), ], optimization:{ minimizer:[ new UglifyJsPlugin({ cache: true, parallel: true, /** * sourceMap 和 devtool: 'inline-source-map', 冲突 */ sourceMap: false, // set to true if you want JS source maps, /** * extractComments 导出备注 */ extractComments: 'all' }), new OptimizeCSSAssetsPlutin({}) ] } } module.exports=merge(common,prodConfig);
还有在package.json中记得把执行命令的--config改一下
{ "name": "webpack1", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "npx webpack --config webpack.dev.js", "dist": "npx webpack --config webpack.prod.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.6.0", "@babel/plugin-transform-runtime": "^7.6.0", "@babel/preset-env": "^7.6.0", "@babel/runtime-corejs2": "^7.6.0", "autoprefixer": "^9.6.1", "babel-loader": "^8.0.6", "clean-webpack-plugin": "^3.0.0", "css-loader": "^3.2.0", "file-loader": "^4.2.0", "html-webpack-plugin": "^3.2.0", "image-webpack-loader": "^6.0.0", "mini-css-extract-plugin": "^0.8.0", "node-sass": "^4.12.0", "optimize-css-assets-webpack-plugin": "^5.0.3", "postcss-loader": "^3.0.0", "sass-loader": "^8.0.0", "style-loader": "^1.0.0", "uglifyjs-webpack-plugin": "^2.2.0", "url-loader": "^2.1.0", "webpack": "^4.39.3", "webpack-cli": "^3.3.8", "webpack-merge": "^4.2.2" }, "dependencies": { "@babel/polyfill": "^7.6.0", "@babel/runtime": "^7.6.0", "lodash": "^4.17.15" } }
------------------------------------------------------------------------------------------------------------------------------
js启用sourcemap
webpack4默认可以启用sourcemap
只需要在config文件中加上:(这个通常放在开发环境中)
devtool:'inline-source-map'
这样在开发环境下,就可以看到执行的js具体是在哪个文件下的第几行执行的
-----------------------------------------------------------------------------------------------------------------
监控文件变化,启用watch,当代码发生变化时,自动编译,自动打包
在webpack启动的时候 加上一个 --watch命令
"scripts": { "test": "echo "Error: no test specified" && exit 1", "build": "npx webpack --watch --config webpack.dev.js", "dist": "npx webpack --config webpack.prod.js" },
-------------------------------------------------------------------------------------------------------------------
webpack-dev-server和热更新
webpack-dev-server提供了一个Web服务器,能够实加载,它内置了webpack的编译功能,是直接编译在内存里,而不是编译在dist文件里,
先安装webpack-dev-server
npm install --save-dev webpack-dev-server
在webpack.dev.js:
const path = require("path"); const merge = require('webpack-merge');//引入webpack-merge参数 const common = require('./webpack.common');//将webpack.common.js引入 const webpack = require('webpack'); let devConfig={ mode:"development",//模式是开发环境 devtool:'inline-source-map',//开启sourcemap 方便js调试 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.js", path:path.resolve(__dirname,"dist") }, devServer: { contentBase: path.join(__dirname,"dist"), //告诉服务器 哪里提供内容,默认情况下将使用当前工作目录作为提供内容的目录 port: 8080, //端口号设为8080, 默认也是8080 clientLogLevel:'warning',//可能的值none、error、warning、info(默认值) hot:true,//启用webpack的模块热替换特性,这个需要配合webpack.HotModuleReplacementPlugin插件 compress:true,//一切服务都启用gzip压缩 host:'localhost',//指定使用一个host,默认是localhost,如果你希望服务器外部可访问0.0.0.0 open:true,//是否打开浏览器 overlay:{//出现错误或者警告的时候,是否覆盖页面线上错误消息 warnings:true, errors:true }, publicPath:'/',//此路径下的打包文件 可在浏览器上访问 proxy:{ "/api":{ target:"http://192.168.0.102:8080", pathRewrite:{ "^/api":"/mockjsdata/5/api", // /api/getuser => http://192.168.0.102:8080/mockjsdata/5/api/getuser } } }, quiet:true,//启动quiet后,除了初始启动信息之外的任何内容都不会显示 watchOptions:{//监视文件相关控制选项 poll:true,//webpack使用文件系统(file system)获取文件改动的通知,在某些情况下不会正常工作 ignored:/node_modules/,//忽略监控的文件夹,正则 aggregateTimeout:300,//默认值,当第一个文件改变,会在重新构建前增加延迟 } }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: ["style-loader",{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], } ] }, plugins:[ new webpack.NamedModulesPlugin(),//更容易查看path 的估值 new webpack.HotModuleReplacementPlugin(),//替换插件 ] } module.exports=merge(common,devConfig);//第一个参数是基本配置 后面的参数是当前配置
之后执行 npx webpack-dev-server --config webpack.dev.js 就会打开服务器,另外需要注意的是,webpack-dev-server内置了webpack的打包功能,但是它时打包到了内存中,而不是dist文件中
当然每次这样执行命令太长了,就把它加到script的命令中:
"start": "npx webpack-dev-server --config webpack.dev.js"
-------------------------------------------------------------------------------------------------------------
babel优化
js启用babel转码:es6转化为es5
安装
npm i -D babel-loader babel-core babel-preset-env
在公共webpack.common.js中添加:
module: {
rules: [
{
},
]
},
记得在根目录下创建一个.babelrc文件
{ "presets": ["@babel/env"] }
----------------------------------
另外 我们在项目中可能在多个模块中重复引用同个文件,这样当babel转码时会一次性将这些重复文件都转码过去,造成文件体积变大,此时需要用到插件,将这些公共的文件提取出来。
npm install babel-plugin-transform-runtime --save-dev
npm install babel-runtime --save
在.babelrc中配置:
{ "presets": ["@babel/env"] }
------------------------------------------------------------------------------------------
eslint校验:
安装:
npm install eslint --save-dev
npm install eslint-loader --save-dev
以下是用到的额外的需要安装的eslint的解释器、校验规则等
npm i -D babel-eslint standard
在common.js中增加配置
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports={ entry:"./src/index.js",//入口文件 module: { rules: [ { test: /.js$/, exclude: /node_modules/, use:[{ loader: 'babel-loader', options:{ cacheDirectory:true,//开启缓存 加快babel转码 } },{//一定要放在下面 先执行eslint检测 再转义 因为webpack是从后往前执行的 loader:'eslint-loader', options:{ fix:true,//如有语法错误 自动修复 } }] }, {//处理图片 路径 test:/.(png|svg|gif|jpg|jpeg)$/, include:[path.resolve(__dirname,'src/')], use:[ { loader:'url-loader', options:{//小于10000字节的图片转换成base64格式 limit:10000 } }, { loader: 'image-webpack-loader', }, ] } ] }, plugins: [ new HtmlWebpackPlugin({ title:"webpack 温习",//默认值webpack App filename:"main.html",//默认值index.html 是最终生成的文件名字 template:path.resolve(__dirname,"src/index.html"), minify:{ collapseWhitespace:true,//是否去空白 removeComments:true,//是否移除注释 removeAttributeQuotes:true,//移除属性的引号 } }), new CleanWebpackPlugin(),//清理构建文件夹 ], }
在跟目录添加.eslintrc.js文件
module.exports={ root:true,//是不是我们的根目录 parserOptions: { parser:'babel-eslint' }, env:{ browser:true, }, extends:[ 'standard' ], globals:{ NODE_ENV:false }, rules:{ 'generator-star-spacing':'off', 'no-debugger': process.env.NODE_ENV === 'production' ? 'error':'off', //添加分号 必须 'semi':['error','always'], 'no-unexpected-multiline':'off', 'space-before-function-paren':['error','never'], 'quotes':[ 'error', 'single', { 'avoidEscape':true } ] } }
在根目录加.eslintignore文件
/dist/ /node-modules/ /*.js
--------------------------------------------------------------------------------------------
resolve解析,当我们引入一个文件时,比如import _ from './src/dev.js'
我们可以将路径配置一个别名,方便引入模块
在common.js中可以加一条配置:
const path = require("path"); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const OptimizeCSSAssetsPlutin=require('optimize-css-assets-webpack-plugin'); const UglifyJsPlugin = require("uglifyjs-webpack-plugin"); const HtmlWebpackPlugin = require("html-webpack-plugin"); const {CleanWebpackPlugin} = require('clean-webpack-plugin'); module.exports={ entry:"./src/index.js",//入口文件 resolve:{ alias:{ '@':path.resolve(__dirname,'src/') }, extensions:[".js",".vue",".json"],//默认.js .json }, module: { rules: [ { test: /.js$/, exclude: /node_modules/, use:[{ loader: 'babel-loader', options:{ cacheDirectory:true,//开启缓存 加快babel转码 } },{//一定要放在下面 先执行eslint检测 再转义 因为webpack是从后往前执行的 loader:'eslint-loader', options:{ fix:true,//如有语法错误 自动修复 } }] }, {//处理图片 路径 test:/.(png|svg|gif|jpg|jpeg)$/, include:[path.resolve(__dirname,'src/')], use:[ { loader:'url-loader', options:{//小于10000字节的图片转换成base64格式 limit:10000 } }, { loader: 'image-webpack-loader', }, ] } ] }, plugins: [ new HtmlWebpackPlugin({ title:"webpack 温习",//默认值webpack App filename:"main.html",//默认值index.html 是最终生成的文件名字 template:path.resolve(__dirname,"src/index.html"), minify:{ collapseWhitespace:true,//是否去空白 removeComments:true,//是否移除注释 removeAttributeQuotes:true,//移除属性的引号 } }), new CleanWebpackPlugin(),//清理构建文件夹 ], }
---------------------------------------------------------------------------------
webpack 配置外部拓展(externals) cdn也可以全局引入
在common.js中再增加一个配置 已引入jquery为例
externals:{ jquery:"jQuery",//写法有多种可以查一下 },
这样就可以在main,js中import $ from 'jquery' 来全局引入jquery 另外这样做有个好处就是 jquery不会打包到bundle里去 大大减少文件体积
-----------------------------------------------------------------------------------------
如何让webpack打包后生成分析报表
安装
npm install --save-dev webpack-bundle-analyzer
在dev.js中配置
const path = require("path"); const merge = require('webpack-merge');//引入webpack-merge参数 const common = require('./webpack.common');//将webpack.common.js引入 const webpack = require('webpack'); const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; let devConfig={ mode:"development",//模式是开发环境 devtool:'inline-source-map',//开启sourcemap 方便js调试 output:{//出口文件时main.js,打包到当前目录的dist文件夹下 filename:"main.js", path:path.resolve(__dirname,"dist") }, devServer: { contentBase: path.join(__dirname,"dist"), //告诉服务器 哪里提供内容,默认情况下将使用当前工作目录作为提供内容的目录 port: 8080, //端口号设为8080, 默认也是8080 clientLogLevel:'warning',//可能的值none、error、warning、info(默认值) hot:true,//启用webpack的模块热替换特性,这个需要配合webpack.HotModuleReplacementPlugin插件 compress:true,//一切服务都启用gzip压缩 host:'localhost',//指定使用一个host,默认是localhost,如果你希望服务器外部可访问0.0.0.0 open:true,//是否打开浏览器 overlay:{//出现错误或者警告的时候,是否覆盖页面线上错误消息 warnings:true, errors:true }, publicPath:'/',//此路径下的打包文件 可在浏览器上访问 proxy:{ "/api":{ target:"http://192.168.0.102:8080", pathRewrite:{ "^/api":"/mockjsdata/5/api", // /api/getuser => http://192.168.0.102:8080/mockjsdata/5/api/getuser } } }, quiet:true,//启动quiet后,除了初始启动信息之外的任何内容都不会显示 watchOptions:{//监视文件相关控制选项 poll:true,//webpack使用文件系统(file system)获取文件改动的通知,在某些情况下不会正常工作 ignored:/node_modules/,//忽略监控的文件夹,正则 aggregateTimeout:300,//默认值,当第一个文件改变,会在重新构建前增加延迟 } }, module: { rules: [ { test: /.(sc|c|sa)ss$/,//scss,css,sass use: ["style-loader",{ loader:"css-loader", options:{ sourceMap:true } },{ loader:"postcss-loader", options:{ ident:"postcss",//唯一标识,建议使用postcss sourceMap:true, plugins:(loader)=>[ require("autoprefixer")({overrideBrowserslist:["> 0.15% in CN"]}),//浏览器 份额大于0.15% 在中国 (已经包括IE8了) ] } },{ loader:"sass-loader", options:{ sourceMap:true } }], } ] }, plugins:[ new webpack.NamedModulesPlugin(),//更容易查看path 的估值 new webpack.HotModuleReplacementPlugin(),//替换插件 new BundleAnalyzerPlugin(),//生成打包报表 ] } module.exports=merge(common,devConfig);//第一个参数是基本配置 后面的参数是当前配置
然后 打包一下,就会出现报表