前言

手摸手教你如何打包,让你在入手的实际过程中感触webpack。
在入手之前,你可先简略理解一下webpack的概念
每一小结都有对应的分支,不便大家学习
webpack版本:5.58.1

入门

新建一个目录,初始化npm
npm init
接下来装置webpackwebpack-cli两个包
npm i -D webpack webpack-cli

默认配置

新建一个文件夹src ,外面新建一个main.js,写一点测试代码
console.log("webpack")
在package.json中scripts中增加新的命令

"scripts": {  "build": "webpack ./src/main.js"},

执行打包命令npm run build
此时如果生成了一个dist文件夹,并且外部含有main.js阐明曾经打包胜利了
这个例子只是webpack本人默认的配置,上面咱们要实现更加丰盛的自定义配置

自定义配置

新建一个build文件夹,外面新建一个webpack.config.js

const path = require('path');module.exports = {  mode:'development', // 开发模式  entry: path.resolve(__dirname,'../src/main.js'), // 入口文件  output: {      filename: 'output.js', // 打包后的文件名称      path: path.resolve(__dirname,'../dist') // 打包后的目录  }}

更改打包命令

{  // ...  "scripts": {    "build": "webpack --config build/webpack.config.js"  },}

而后执行 npm run build,会失去如下后果

其中main.js是咱们第一次打包遗留的。
js曾经打包好了,接下来咱们要做的就是将js引入到html文件中

增加js到html文件

咱们须要html-webpack-plugin来帮咱们实现这件事件
npm i -D html-webpack-plugin
新建一个与build同级的文件夹public,外面新建一个index.html
配置如下

const path = require('path');const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {  mode:'development', // 开发模式  entry: path.resolve(__dirname,'../src/main.js'), // 入口文件  output: {      filename: '[name].[hash:8].js', // [name] 指entry属性名字, 默认为main      path: path.resolve(__dirname,'../dist') // 打包后的目录  },  plugins:[    new HtmlWebpackPlugin({      // 选取一个html作为模版,在dist目录下会生成一个雷同的html,之后将打包好的js注入到该html文件      template: path.resolve(__dirname,'../public/index.html')     })  ]}

打包胜利之后,查看dist目录下的index.html文件是否援用了打包之后的js

多文件如何注入到html

  1. 多个入口文件,注入到同一个html文件中

这种情景咱们只需增加入口就OK了,html-webpack-plugin插件会主动把所有打包好的js注入到html里

module.exports = {  // ...  entry: {    main: path.resolve(__dirname,'../src/main.js'),    share: path.resolve(__dirname,'../src/share.js')  }}
  1. 多个入口文件,依据不同需要注入到不同的html文件

咱们能够通过生成多个html-webpack-plugin实例来解决这个问题

module.exports = { // ...  plugins:[    new HtmlWebpackPlugin({      // 选取一个html作为模版,在dist目录下会生成一个雷同的html,之后将打包好的js注入到该html文件      template: path.resolve(__dirname,'../public/index.html'),      filename: 'index.html',      chunks: ['main'] // 配置将哪些文件注入到该html文件,为[]在代表不注入js,若无该属性,默认注入所有js    }),    new HtmlWebpackPlugin({      template: path.resolve(__dirname,'../public/share.html'),      filename: 'share.html',      chunks: ['share']    })  ] }

打包前清空dist目录

置信大家也发现了,dist目录下的文件越来越多,上面咱们就来解决这个问题
咱们须要clean-webpack-plugin来帮咱们实现这件事件
npm i -D clean-webpack-plugin

// 其余配置同上const { CleanWebpackPlugin } = require('clean-webpack-plugin')module.exports = {   plugins:[    // ...    new CleanWebpackPlugin()  ] }

经掘友揭示,webpack5有新增清空dist目录的形式,在output减少clean字段,现补充在上面

module.exports = {  // ...  output: {      filename: '[name].[hash:8].js', // [name] 指entry属性名字, 默认为main      path: path.resolve(__dirname,'../dist'), // 打包后的目录      clean: true  },}

将css以style标签的形式注入到html

咱们的入口文件是js,所以咱们在入口js中引入咱们的css文件

// main.jsimport "../static/css/base.css"import "../static/css/color.scss"import "../static/css/fontsize.less"console.log("webpack")

咱们须要一些loader来解析咱们的css文件
npm i -D style-loader css-loader
如果应用less来构建款式,则须要装置
npm i -D less less-loader
如果应用scss来构建款式,则须要装置
npm i -D node-sass sass-loader
配置文件如下

module.exports = {  // ...  module: {    rules: [      {        test: /\.css$/,        use: ["style-loader", "css-loader"] // 从右向左开始解析      },      {        test: /\.scss$/,        use: ["style-loader", "css-loader", "sass-loader"] // 此外还须要装置node-sass(sass也行)      },      {        test:/\.less$/,        use:['style-loader','css-loader','less-loader'] // 此外还须要装置less模块      }    ]  }}

打包之后在浏览器中关上html文件,就能看见咱们注入的css

为css增加浏览器前缀

为了适配更多的浏览器款式咱们须要给css加上前缀
咱们须要postcss-loader以及autoprefixer来帮咱们实现这件事件

参考webpack视频解说:进入学习

引入autoprefixer形式有两种

  1. postcss.config.js引入(举荐)

**我的项目根目**录下创立postcss.config.js,配置如下

module.exports = {  plugins: [    require('autoprefixer')  ]}

而后间接在webpack.config.js中引入

module.exports = {  // ...  module: {    rules: [      {        test: /\.css$/,        use: ["style-loader", "css-loader", "postcss-loader"] // 从右向左开始解析      },      {        test: /\.scss$/,        use: ["style-loader", "css-loader", "postcss-loader", "sass-loader"] // 此外还须要装置node-sass(sass也行)      },      {        test:/\.less$/,        use:['style-loader','css-loader', "postcss-loader", 'less-loader'] // 此外还须要装置less模块      }    ]  } }
  1. 间接在webpack.config.js配置
moudule.exports = { // ...  module: {    rules: [      {        test: /\.css$/,        use: ["style-loader", "css-loader", {          loader: "postcss-loader",          options: {            postcssOptions: {              plugins: [                ['autoprefixer']              ]            }          }        }] // 从右向左开始解析      },      {        test: /\.scss$/,        use: ["style-loader", "css-loader", {          loader: "postcss-loader",          options: {            postcssOptions: {              plugins: [                ['autoprefixer']              ]            }          }        }, "sass-loader"] // 此外还须要装置node-sass(sass也行)      },      {        test:/\.less$/,        use:['style-loader','css-loader', {          loader: "postcss-loader",          options: {            postcssOptions: {              plugins: [                ['autoprefixer']              ]            }          }        }, 'less-loader'] // 此外还须要装置less模块      }    ]  } }

实现上述配置之后,咱们发现css并未胜利加上前缀。这里咱们还要进行一步操作,那就是配置package.json,在package.json中增加如下配置

{ // ..."browserslist": [    "defaults",    "not ie < 11",    "last 2 versions",    "> 1%",    "iOS 7",    "last 3 iOS versions"  ]}

外链引入css文件

上述咱们通过style标签的形式加载咱们的款式,但如果css文件过多就显得很凌乱。
咱们须要mini-css-extract-plugin帮咱们实现
npm i -D mini-css-extract-plugin

// 其余配置放弃不变const MiniCssExtractPlugin = require("mini-css-extract-plugin");module.exports = {  // ...  plugins: [    // ...    new MiniCssExtractPlugin({      filename: "[name].[hash].css",    })  ],    module: {    rules: [      {        test: /\.css$/,        use: [MiniCssExtractPlugin.loader, "css-loader", "postcss-loader"] // 从右向左开始解析      },      {        test: /\.scss$/,        use: [MiniCssExtractPlugin.loader, "css-loader", {          loader: "postcss-loader",          options: {            postcssOptions: {              plugins: [                ['autoprefixer']              ]            }          }        }, "sass-loader"] // 此外还须要装置node-sass(sass也行)      },      {        test:/\.less$/,        use:[MiniCssExtractPlugin.loader,'css-loader', "postcss-loader", 'less-loader'] // 此外还须要装置less模块      }    ]  }}

不过通过这种形式会将所有的css合并到一个css文件里,如果想要拆分就只有用其余方法里,网上看他人用的是extract-text-webpack-plugin,不过当我去npm官网看时。

所以这里就先不探讨拆分css了

图片解决

css与js中图片解决只需增加如下配置就行

module.exports = {    // ...  module: {    rules: [        // ...      {        test: /\.(jpe?g|png|gif)$/i,        type: "asset",        generator: {          filename: 'static/[name].[hash].[ext]'        }      },    ]  }}

如果须要解决html中的图片则须要用到html-loader
npm i -D html-loader
配置如下

module.exports = {    // ...  module: {    rules: [        // ...      {        test: /\.html$/i,        loader: "html-loader"      },    ]  }}

如果须要配置更多的资源文件,请参考资源模块

本义js文件

为了使咱们的js代码兼容更多的环境咱们须要本义咱们的js文件
npm i -D babel-loader @babel/preset-env @babel/core core-js

module.expors = {  // ...  module: {    rules: [      // ...      {        test: /\.js$/,        use: {          loader: 'babel-loader',          options: {            presets: [              [                '@babel/preset-env',                {                  useBuiltIns: 'usage',                  corejs: {                    //core-js的版本                    version: 3                  },                  //须要兼容的浏览器                  targets: {                    chrome: '60',                    firefox: '60',                    ie: '9',                    safari: '10',                    edge: '17'                  }                }              ]            ],          }        },        exclude: /node_modules/      }    ]  }}

babel-loader负责将ES6/7/8等语法转换为ES5语法
core-js负责将新的api进行转化,例如promise、Generator、Set、Maps、Proxy等

进阶

搭建Vue开发环境

Vue文件解决

首先装置必要依赖
npm i -D vue-loader vue-template-compiler vue-style-loader
npm i -S vue
vue-loader 用于解析.vue文件
vue-template-compiler 用于编译模板
vue-style-loader 解析款式

const vueLoaderPlugin = require('vue-loader/lib/plugin')module.exports = {  // ...  module:{    rules:[      // 这一个loader必须放在最后面      {        test:/\.vue$/,        use:['vue-loader']      }      // ...    ]  },  resolve:{    // 设置门路别名    alias:{      'vue$':'vue/dist/vue.runtime.esm.js',      '@':path.resolve(__dirname,'../src')    },    // 尝试按程序解析这些后缀名。    // 如果有多个文件有雷同的名字,但后缀名不同,webpack 会解析列在数组首位的后缀的文件 并跳过其余的后缀。    extensions:['*','.js','.json','.vue']  },  plugins:[    new vueLoaderPlugin()  ]}

热更新配置

咱们须要应用webpack-dev-server来启动一个本地服务并且配置热更新
npm i -D webpack-dev-server
配置如下

const Webpack = require('webpack')module.exports = {  // ...  devServer:{    port:3000,    hot:true  },  plugins:[    new Webpack.HotModuleReplacementPlugin()  ]}

配置打包命令

"scripts": {  // ...  "dev": "webpack-dev-server --config build/webpack.config.js --open"},

增加 --open可主动关上 http://localhost:3000页面
接下来写几行代码进行测试,先批改咱们的main.js

// main.jsimport Vue from 'vue'import App from './App.vue'new Vue({  render: h => h(App)}).$mount('#app')

新建一个App.vue文件

<template>  <div>    {{msg}}  </div></template><script>export default {  data() {    return {      msg: "webpack vue"    }  }}</script><style lang='scss' scoped>div {  color: aquamarine;  display: flex;}</style>

批改原来的index.html

<!DOCTYPE html><html lang="en"><head>  <meta charset="UTF-8">  <meta http-equiv="X-UA-Compatible" content="IE=edge">  <meta name="viewport" content="width=device-width, initial-scale=1.0">  <title>webpack</title></head><body>  <div id="app"></div></body></html>

最初执行npm run dev

辨别开发环境和生产环境

development(开发环境)production(生产环境) 这两个环境下的构建指标存在着微小差别。在开发环境中,咱们须要:弱小的 source map 和一个有着 live reloading(实时从新加载) 或 hot module replacement(热模块替换) 能力的 localhost server。而生产环境指标则转移至其余方面,关注点在于压缩 bundle、更轻量的 source map、资源优化等,通过这些优化形式改善加载工夫。因为要遵循逻辑拆散,咱们通常倡议为每个环境编写彼此独立的 webpack 配置。
咱们在原来webpack.config.js的根底上再新增两个文件webpack.prod.jswebpack.dev.js
这里咱们须要应用webpack-merge帮咱们merge代码
npm i -D webpack-merge

// webpack.dev.jsconst { merge } = require('webpack-merge');const common = require('./webpack.config.js')module.exports = merge(common, {  mode: 'development',  devtool: 'inline-source-map',  devServer:{    port:3000,    hot:true  }});
// webpack.prod.jsconst { merge } = require('webpack-merge');const common = require('./webpack.config.js');module.exports = merge(common, {  mode: 'production',});

原先的webpack.config.js也须要做出批改,咱们只须要删除modedevserver字段就行了
最初批改package.json中的scripts命令

"scripts": {    "build": "webpack --config build/webpack.prod.js",    "dev": "webpack-dev-server --config build/webpack.dev.js --open"  },

开发环境运行npm run dev,打包npm run build

最初

码字不易,若是对你有帮忙,那就点个赞吧