初始化一个web项目
使用npm init -y 初始化一个项目
在项目目录下创建src, dist文件夹,创建webpack.config.js配置文件
然后在src文件夹下创建index.js, index.html文件
1 2 3 4 5 6 7 8 9 | 然后安装依赖包 npm i jquery -S 安装jQuery包 npm i webpack webpack-cli webpack-dev-server html-webpack-plugin -D 安装开发调试包 安装loader调试工具 yarn add style-loader css-loader sass-loader node-sass url-loader file-loader --dev 安装babel预编译工具, babel-loader@7需要添加版本号,否则可能导致babel-loader与babel-core版本不兼容问题 yarn add babel-loader@7 babel-core babel-plugin-transform-runtime babel-preset-env babel-preset-stage-0 babel-preset-react --dev 安装项目工具和UI库 yarn add react react-dom react-router-dom@4.2.2 antd@5.10.1 |
编写index.js脚本文件
1 2 3 4 5 6 | import $ from 'jquery' $( function () { $( 'li:odd' ).css( 'backgroundColor' , 'pink' ) $( 'li:even' ).css( 'backgroundColor' , 'lightblue' ) }) |
在index.html中导入index.js脚本文件
1 2 3 4 5 6 |
|
编写webpack.config.js配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | const path = require( 'path' ) const htmlWebpackPlugin = require( 'html-webpack-plugin' ) module.exports = { mode: 'development' , //项目的入口与出口设置 entry: path.join(__dirname, './src/index.js' ), output: { path: path.join(__dirname, './dist' ), filename: 'bundle.js' }, plugins: [ //插件 //在内存中生成一个页面,默认在项目的根目录下的内存中 new htmlWebpackPlugin({ //页面模板 template: path.join(__dirname, './src/index.html' ), filename: 'index.html' }) ] } |
在package.json项目配置中添加短命令
1 2 3 4 5 | "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" , // --cacheBase: 指定托管目录, 如果没指定默认在项目内存的根目录下 "dev" : "webpack-dev-server --open --port 3000 --hot" }, |
执行npm run dev 进行打包调试
添加调试工具
添加loader加载器和babel预编译工具
添加loader加载器,让webpack处理js模块外的其他模块。
webpack默认只能打包处理以.js结尾的模块。其他非.js后缀名结尾的模块,webpack默认是不处理的。
需要调用loader加载器才可以正常打包,loader加载器的作用:协作webpack打包处理约定的文件模块。比如:css-loader: 可以打包处理.css相关的文件。
1 2 3 4 5 6 7 8 9 10 11 12 13 | 使用scss设置css样式,需要使用css-loader解析器进行解析 npm i style-loader css-loader sass-loader node-sass url-loader file-loader -D js中es6高级语法解析 npm i babel-core babel-loader babel-plugin-transform-runtime babel-preset-env babel-preset-stage-0 -D 在webpack.config.js中添加loader加载器配置 module: { rules: [ { test: /\.css$/, use:[ 'style-loader' , 'css-loader' ] }, { test: /\.scss$/, use:[ 'style-loader' , 'css-loader' , 'sass-loader' ] }, { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=500000' }, { test: /\.js$/, use: 'babel-loader' , exclude: /node_modules/ }, ] } |
开发完成,打包发布
新建发布配置文件webpack.pub.config.js
修改它的产物名称配置文件
1 2 3 4 5 6 7 8 | module: { rules: [ { test: /\.css$/, use:[ 'style-loader' , 'css-loader' ] }, { test: /\.scss$/, use:[ 'style-loader' , 'css-loader' , 'sass-loader' ] }, { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=5000&name=[hash:8]-[name].[ext]' }, { test: /\.js$/, use: 'babel-loader' , exclude: /node_modules/ }, ] } |
在package.json配置文件中,添加短命令pub,并在webpack命令中添加使用的配置文件名参数
1 2 3 4 5 6 | "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" , "--cacheBase" : "指定托管目录, 如果没指定默认在项目内存的根目录下" , "dev" : "webpack-dev-server --open --port 3000 --hot" , "pub" : "webpack --config webpack.pub.config.js" }, |
调用指令npm run pub, 打包出资源bundle.js, 图片, index.html。
1 2 3 4 5 6 7 8 9 10 | zhoufeideMacBook-Pro-2:webpack zhoufei$ npm run pub > webpack@1.0.0 pub > webpack --config webpack.pub.config.js assets by path *.jpg 61.5 KiB asset 56e2b290-phone1.jpg 61.5 KiB [emitted] [immutable] [from: src/images/phone1.jpg] (auxiliary name: main) asset 7a417220207de157cf21.jpg 63 bytes [emitted] [immutable] [from: src/images/phone1.jpg] (auxiliary name: main) asset bundle.js 344 KiB [emitted] (name: main) asset index.html 660 bytes [emitted] |
webpack编译器优化
1.产物图片优化
把项目中的所有图片在产物中放到一个images文件夹下面
通过修改webpack.pub.config.js中的module.rules项
1 | { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=5000&name=images/[hash:8]-[name].[ext]' }, |
2.产物目录dist重建优化
每次生成产物时,都对dist目录进行先清理,再生成
1 2 3 4 5 6 7 8 9 10 11 | npm i clean-webpack-plugin -D webpack.pub.config.js中进行配置清理插件 const { CleanWebpackPlugin } = require( 'clean-webpack-plugin' ); plugins: [ //插件 /* 每次构建产物都要重新创建dist目录保存产物 */ new CleanWebpackPlugin({cleanAfterEveryBuildPatterns:[ 'dist' ]}) ], |
3.抽离第三方包
发布思路:bundle.js中只存放自己的代码,第三方包的代码都抽离到另外的JS包中
webpack@4以后的版本,弃用了许多@3的插件,其中包括:
1 2 3 4 5 | 分离打包js文件的插件 webpack.optimize.CommonChunkPlugin(); 压缩js文件的插件 webpack.optimize.UglifyJsPlugin(); 定义产品上线环境webpack.optimize.DedupePlugun(); 分离css文件插件extract-text-webpack-plugin(); css文件压缩插件 CssMinimizerPlugin(); |
webpack3的抽离方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | 在webpack.pub.config.js中修改entry的设置为如下: //app和vendors的key名称都是自己自定义的,随便取的 entry: { app: path.join(__dirname, './src/index.js' ), vendors: [ 'jquery' ] //把要抽离的第三方包放到这个数组中 }, 在pulgins的数组中添加抽离设置 new webpack.optimize.CommonsChunkPlugin({ name: 'vendors' , //指定抽离的入口 filename: 'vendors.js' //抽离的所有第三方包的结果包名称。 }) 然后将js文件放到一个统一的目录下: output: { path: path.join(__dirname, './dist' ), filename: 'js/bundle.js' }, |
4.压缩js代码
在webpack.pub.config.js中的 plugins项目下,添加下面的js优化代码
1 2 3 4 5 6 7 8 9 | js代码压缩优化 new webpack.optimize.UglifyJsPlugin({ compress: { //配置压缩项 warnings: false //移除警告 } }), new webpack.optimize.DedupePlugin({ 'process.env.NODE_ENV' : '"production"' }) |
5.压缩html代码
1 2 3 4 5 6 7 8 9 10 11 | 在htmlWebpackPlugin模板中添加html优化配置 new htmlWebpackPlugin({ //页面模板 template: path.join(__dirname, './src/index.html' ), filename: 'index.html' , minify: { collapseWhitespace: true , //合并多余的空格 removeComments: true , // 移除注释 removeAttributeQuotes: true //移除属性上的双引号 } }), |
6.从bundle.js中抽离css单独存放
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | yarn add extract-text-webpack-plugin --dev 修改webpack.pub.config.js文件 const ExtractTextPlugin = require( 'extract-text-webpack-plugin' ) 添加插件 plugins: [ //插件 //配置提取出来的css名称 new ExtractTextPlugin({ filename: 'style/[name].min.css' }) ], 修改css-loader的rules module: { rules: [ { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader' , use: 'css-loader' , publicPath: '../' //指定抽离的时候,自动为我们使用的路径加上 ../前缀 }) }, { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader' , use: [ 'css-loader' , 'sass-loader' ], publicPath: '../' //指定抽离的时候,自动为我们使用的路径加上 ../前缀 }) }, ] } |
7.压缩css
1 2 3 4 5 6 7 8 9 10 11 12 | yarn add optimize-css-assets-webpack-plugin --dev 修改webpack.pub.config.js文件 // 压缩css插件 const OptimizeCssAssetsPlugin = require( 'optimize-css-assets-webpack-plugin' ) plugins: [ //插件 /* 压缩css */ new OptimizeCssAssetsPlugin() ], |
webpack项目模板
dev的webpack开发模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | const path = require( 'path' ) const htmlWebpackPlugin = require( 'html-webpack-plugin' ) const { name } = require( 'file-loader' ) module.exports = { mode: 'development' , //项目的入口与出口设置 entry: path.join(__dirname, './src/index.js' ), output: { path: path.join(__dirname, './dist' ), filename: 'bundle.js' }, plugins: [ //插件 //在内存中生成一个页面,默认在项目的根目录下的内存中 /* html-webpack-plugin的作用有2个: 1.自动将./src/index.html页面复制一份到项目根目录,放到了内存中。 2.在内存中自动生成的index.html页面里,自动注入webpack打包的存在于内存中的bundle.js文件 */ new htmlWebpackPlugin({ //页面模板 template: path.join(__dirname, './src/index.html' ), filename: 'index.html' }) ], /* webpack默认只能打包处理以.js结尾的模块。其他非.js后缀名结尾的模块,webpack默认是不处理的。 需要调用loader加载器才可以正常打包,loader加载器的作用:协作webpack打包处理约定的文件模块。比如:css-loader: 可以打包处理.css相关的文件。 */ module: { rules: [ { test: /\.css$/, use:[ 'style-loader' , 'css-loader' ] }, //声明css模块化,使用CSS模块化解决多个css的作用域都是全局作用域,导致结果互相覆盖的情况 //一般第三方库的样式文件是以css结尾的,所以不能直接对css开启模块化,会影响其他第三方库的展示,这里只对scss进行开启模块化 // { test: /\.css$/, use:['style-loader', { // loader: 'css-loader', // options: { // importLoaders: 1, // modules: true, // //自定义css模块化后的class名称 // // localIdentName: [name]-[local]-[hash:5] // } // }] }, { test: /\.scss$/, use:[ 'style-loader' , { loader: 'css-loader' , options: { importLoaders: 1, modules: true , //自定义css模块化后的class名称 // localIdentName: [name]-[local]-[hash:5] } }, 'sass-loader' ] }, { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=500000' }, { test: /\.jsx?$/, use: 'babel-loader' , exclude: /node_modules/ }, ] } } |
pub的webpack发布模板
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | const path = require( 'path' ) const htmlWebpackPlugin = require( 'html-webpack-plugin' ) //导入每次删除文件夹的插件 const { CleanWebpackPlugin } = require( 'clean-webpack-plugin' ); const webpack = require( 'webpack' ) // 抽取Css插件 const ExtractTextPlugin = require( 'extract-text-webpack-plugin' ) // 压缩css插件 const OptimizeCssAssetsPlugin = require( 'optimize-css-assets-webpack-plugin' ) module.exports = { mode: 'production' , //项目的入口与出口设置 entry: path.join(__dirname, './src/index.js' ), //app和vendors的key名称都是自己自定义的,随便取的 // entry: { // app: path.join(__dirname, './src/index.js'), // vendors: ['jquery'] //把要抽离的第三方包放到这个数组中 // }, output: { path: path.join(__dirname, './dist' ), filename: 'js/bundle.js' }, plugins: [ //插件 //在内存中生成一个页面,默认在项目的根目录下的内存中 /* html-webpack-plugin的作用有2个: 1.自动将./src/index.html页面复制一份到项目根目录,放到了内存中。 2.在内存中自动生成的index.html页面里,自动注入webpack打包的存在于内存中的bundle.js文件 */ new htmlWebpackPlugin({ //页面模板 template: path.join(__dirname, './src/index.html' ), filename: 'index.html' , minify: { collapseWhitespace: true , //合并多余的空格 removeComments: true , // 移除注释 removeAttributeQuotes: true //移除属性上的双引号 } }), /* 每次构建产物都要重新创建dist目录保存产物 */ new CleanWebpackPlugin({cleanAfterEveryBuildPatterns:[ 'dist' ]}), new OptimizeCssAssetsPlugin() /* 编译优化:抽离第三方包名称 webpack3的在plugins数组中添加new webpack.optimize.CommonsChunkPlugin配置方式已经废弃,要在下面的方法进行实现 webpack3实现方法 new webpack.optimize.CommonsChunkPlugin({ name: 'vendors', //指定抽离的入口 filename: 'vendors.js' //抽离的所有第三方包的结果包名称。 }) webpack5设置无效,先注释 */ /* 编译优化:js代码压缩优化 new webpack.optimize.UglifyJsPlugin({ compress: { //配置压缩项 warnings: false //移除警告 } }), new webpack.optimize.DedupePlugin({ 'process.env.NODE_ENV': '"production"' }) */ /* 编译优化:抽离css //配置提取出来的css名称 new ExtractTextPlugin({ filename: 'style/[name].min.css' }) */ ], // webpack V5替代webpack V3的解决方案 // optimization: { // splitChunks: { // cacheGroups: { // commons: { // test: /[\\/]node_modules[\\/]/, // name: 'vendors', // chunks: 'all', // }, // } // } // }, /* webpack默认只能打包处理以.js结尾的模块。其他非.js后缀名结尾的模块,webpack默认是不处理的。 需要调用loader加载器才可以正常打包,loader加载器的作用:协作webpack打包处理约定的文件模块。比如:css-loader: 可以打包处理.css相关的文件。 产物图片优化: 把项目中的所有图片在产物中放到一个images文件夹下面 { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=5000&name=images/[hash:8]-[name].[ext]' }, */ module: { rules: [ { test: /\.css$/, use:[ 'style-loader' , 'css-loader' ] }, //声明css模块化,使用CSS模块化解决多个css的作用域都是全局作用域,导致结果互相覆盖的情况 //一般第三方库的样式文件是以css结尾的,所以不能直接对css开启模块化,会影响其他第三方库的展示,这里只对scss进行开启模块化 // { test: /\.css$/, use:['style-loader', { // loader: 'css-loader', // options: { // importLoaders: 1, // modules: true, // //自定义css模块化后的class名称 // // localIdentName: [name]-[local]-[hash:5] // } // }] }, { test: /\.scss$/, use:[ 'style-loader' , { loader: 'css-loader' , options: { importLoaders: 1, modules: true , //自定义css模块化后的class名称 // localIdentName: [name]-[local]-[hash:5] } }, 'sass-loader' ] }, { test: /\.(png|gif|bmp|jpg)$/, use: 'url-loader?limit=500000' }, { test: /\.jsx?$/, use: 'babel-loader' , exclude: /node_modules/ }, ] } } |
对应package.json依赖关系和scripts短命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | { "name" : "webpack" , "version" : "1.0.0" , "description" : "" , "main" : "index.js" , "scripts" : { "test" : "echo \"Error: no test specified\" && exit 1" , "--cacheBase" : "指定托管目录, 如果没指定默认在项目内存的根目录下" , "dev" : "webpack-dev-server --open --port 3000 --hot" , "pub" : "webpack --config webpack.pub.config.js" }, "keywords" : [], "author" : "" , "license" : "ISC" , "devDependencies" : { "babel-core" : "^6.26.3" , "babel-loader" : "7" , "babel-plugin-transform-runtime" : "^6.23.0" , "babel-preset-env" : "^1.7.0" , "babel-preset-react" : "^6.24.1" , "babel-preset-stage-0" : "^6.24.1" , "clean-webpack-plugin" : "^4.0.0" , "css-loader" : "^6.8.1" , "extract-text-webpack-plugin" : "^3.0.2" , "file-loader" : "^6.2.0" , "html-webpack-plugin" : "^5.5.3" , "node-sass" : "^9.0.0" , "optimize-css-assets-webpack-plugin" : "^6.0.1" , "sass-loader" : "^13.3.2" , "style-loader" : "^3.3.3" , "url-loader" : "^4.1.1" , "webpack" : "^5.89.0" , "webpack-cli" : "^5.1.4" , "webpack-dev-server" : "^4.15.1" }, "dependencies" : { "antd" : "^5.10.1" , "jquery" : "^3.7.1" , "prop-types" : "^15.8.1" , "react" : "^18.2.0" , "react-dom" : "^18.2.0" , "react-router-dom" : "4.2.2" } } |
.babelrc模板
1 2 3 4 | { "presets" : [ "env" , "stage-0" , "react" ], "plugins" : [ "transform-runtime" ] } |