webpack從入門到上手全流程

webpack學(xué)習(xí)路徑,有個青銅就好

《一文徹底解決新手對 webpack 的恐懼!》

webpack是一個現(xiàn)代JavaScript應(yīng)用程序的靜態(tài)模塊打包器。所以webpack本質(zhì)就是為我們打包js的引用,而我們常聽到各種loader、各種plugin、熱更新、熱模塊替換等等都是webpack的一個升華,使得webpack能為我們提供更多的幫助。

loader
總結(jié):loader是處理編譯js和json以外的文件時用的
常見的loader:

style-loader  
css-loader  
sass-loader  
ts-loader  
file-loader  
babel-loader  
postcss-loader  

plugin: plugin可以在webpack運行到某個階段時候,幫你做一些事情,類似react/vue中的生命周期。具體的某個插件(plugin)就是在webpack構(gòu)建過程中的特定時機注入擴展邏輯來改變構(gòu)建結(jié)果,作用于整個構(gòu)建過程。

postcss:postcss是一個用 JavaScript 工具和插件轉(zhuǎn)換 CSS 代碼的工具。

babel:babel 是一個 JavaScript 編譯器,他可以讓我們不再考慮兼容性,盡情的使用下一代的 JavaScript 語法編程。

es6+語法:babel默認(rèn)會轉(zhuǎn)換語法,例如:let、const、() => {}、class

es6+特性:babel不會轉(zhuǎn)換特性,特性需要js代碼墊片來兼容低版本的瀏覽器。

@babel/core:@babel/core是babel的核心庫

@babel/preset-env:這是一個預(yù)設(shè)的插件集合,包含了一組相關(guān)的插件

@babel/polyfill:需要polyfill來做js的墊片,彌補低版本瀏覽器缺失的這些新功能

core-js:它是JavaScript標(biāo)準(zhǔn)庫的polyfill,而且它可以實現(xiàn)按需加載。

egenerator-runtime:提供generator函數(shù)的轉(zhuǎn)碼

browserslist:browserslist實際上就是聲明了一段瀏覽器的合集

// 在.browserslistrc中的寫法  
> 1%  
last 2 versions  
// 在package.json中的寫法  
{  
  "browserslist": ["> 1%", "last 2 versions"]  
}

chunk:它不是庫也不是插件,它就是一個名詞,顧名思義就是代碼塊。
chunks:一個chunks至少包含一個chunk,chunks是多個chunk的合集

webpack配置核心概念
  • chunk:指代碼塊,一個chunk可能由多個模塊組合而成,也用于代碼合并與分割(這里的合并分割主要指指紋策略的判斷),指紋策略簡單來說就是文件名后的hash
  • bundle:資源經(jīng)過webpack流程解析編譯后最終輸出的成果文件(一個.js格式的文件,也就是我們的output文件)
  • entry:文件打包的入口,webpack會根據(jù)entry遞歸的去尋找依賴,每個依賴都將被它處理,最后打包到集合文件中
  • output:配置打包輸出的位置、文件名等
  • loader:默認(rèn)情況下,webpack僅支持js和json文件,通過loader,可以讓它解析其他類型的文件。理論上只要有相應(yīng)的loader,webpack可以處理任何類型的文件
  • plugin:loader主要的職責(zé)是讓webpack認(rèn)識更多的文件類型,而plugin的職責(zé)則是讓其可以控制構(gòu)建流程,從而執(zhí)行一些特殊的任務(wù)。插件的功能非常強大,可以完成各種各樣的任務(wù)
  • mode:目標(biāo)環(huán)境,不用的目標(biāo)環(huán)境會影響webpack打包時的決策
  • production:碼進行壓縮等一系列優(yōu)化操作
  • development:有利于熱更新的處理,識別哪個模塊變化代
  • none:什么都不做,打包時會有提示警告
配置webpack.config.js
const path = require('path')  
const MiniCssExtractPlugin = require('mini-css-extract-plugin')  
const HtmlWebpackPlugin = require('html-webpack-plugin')  
const { CleanWebpackPlugin } = require('clean-webpack-plugin')  
const HtmlPlugin = require('./plugin/htmlPlugin')  
const Webpack = require('webpack')  
  
module.exports = {  
  entry: './src/index.js',  
  output: {  
    filename: 'main.js',  
    path: path.resolve(__dirname, './dist')  
  },  
  mode: 'development',  
  module: {  
    rules: [  
      {  
        test: /\.js$/,  
        use: path.resolve(__dirname, './loader/replaceLoader.js')  
      },  
      {  
        test: /\.css$/,  
        use: [  
          // MiniCssExtractPlugin.loader,  
          'style-loader',  
          'css-loader',  
          'postcss-loader'  
        ]  
      },  
      {  
        test: /\.(png|jpe?g|gif)$/,  
        use: {  
          loader: 'url-loader',  
          options: {  
            name: '[name].[ext]',  
            limit: 1024 * 3,  
            outputPath: "images/",  
            publicPath: "/images",  
          }  
        }  
      }  
    ]  
  },  
  devServer: {  
    open: true,  
    port: 8080,  
    hot: true  
  },  
  plugins: [  
    new MiniCssExtractPlugin({  
      filename: "css/[name].css",  
    }),  
    new HtmlWebpackPlugin({  
      template: './src/index.html'  
    }),  
    new CleanWebpackPlugin(),  
    new HtmlPlugin(),  
    new Webpack.HotModuleReplacementPlugin()  
  ]  
}  

《尚硅谷 Web 前端之 Webpack5 教程》

為什么
  • 開發(fā)代碼要想在瀏覽器運行必須經(jīng)過編譯成瀏覽器能識別的 JS、Css 等語法
  • 打包工具還能壓縮代碼、做兼容性處理、提升代碼性能等
5 大核心概念

Webpack 是基于 Node.js 運行的,所以采用 Common.js 模塊化規(guī)范

  1. entry(入口)

指示 Webpack 從哪個文件開始打包

  1. output(輸出)

指示 Webpack 打包完的文件輸出到哪里去,如何命名等

  1. loader(加載器)

webpack 本身只能處理 js、json 等資源,其他資源需要借助 loader,Webpack 才能解析

  1. plugins(插件)

擴展 Webpack 的功能

  1. mode(模式)

主要由兩種模式:

  • 開發(fā)模式:development
    1)編譯代碼,使瀏覽器能識別運行
    2)代碼質(zhì)量檢查,樹立代碼規(guī)范
  • 生產(chǎn)模式:production
    1)優(yōu)化代碼運行性能
    2)優(yōu)化代碼打包速度
處理 js 資源

Webpack 對 js 處理是有限的,只能編譯 js 中 ES 模塊化語法,不能編譯其他語法,導(dǎo)致 js 不能在 IE 等瀏覽器運行,所以我們希望做一些兼容性處理。

  • 針對 js 兼容性處理,我們使用 Babel 來完成
  • 針對代碼格式,我們使用 Eslint 來完成
生產(chǎn)環(huán)境的webpack.config.js配置(基礎(chǔ)版)
const path = require("path");
const ESLintWebpackPlugin = require("eslint-webpack-plugin");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");

// 獲取處理樣式的Loaders
const getStyleLoaders = (preProcessor) => {
  return [
    MiniCssExtractPlugin.loader,
    "css-loader",
    {
      loader: "postcss-loader",
      options: {
        postcssOptions: {
          plugins: [
            "postcss-preset-env", // 能解決大多數(shù)樣式兼容性問題
          ],
        },
      },
    },
    preProcessor,
  ].filter(Boolean);
};

module.exports = {
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "../dist"), // 生產(chǎn)模式需要輸出
    filename: "static/js/main.js", // 將 js 文件輸出到 static/js 目錄中
    clean: true,
  },
  module: {
    rules: [
      {
        // 用來匹配 .css 結(jié)尾的文件
        test: /\.css$/,
        // use 數(shù)組里面 Loader 執(zhí)行順序是從右到左
        use: getStyleLoaders(),
      },
      {
        test: /\.s[ac]ss$/,
        use: getStyleLoaders("sass-loader"),
      },
      {
        test: /\.(png|jpe?g|gif|webp)$/,
        type: "asset",
        parser: {
          dataUrlCondition: {
            maxSize: 10 * 1024, // 小于10kb的圖片會被base64處理
          },
        },
        generator: {
          // 將圖片文件輸出到 static/imgs 目錄中
          // 將圖片文件命名 [hash:8][ext][query]
          // [hash:8]: hash值取8位
          // [ext]: 使用之前的文件擴展名
          // [query]: 添加之前的query參數(shù)
          filename: "static/imgs/[hash:8][ext][query]",
        },
      },
      {
        test: /\.(ttf|woff2?)$/,
        type: "asset/resource",
        generator: {
          filename: "static/media/[hash:8][ext][query]",
        },
      },
      {
        test: /\.js$/,
        exclude: /node_modules/, // 排除node_modules代碼不編譯
        loader: "babel-loader",
      },
    ],
  },
  plugins: [
    new ESLintWebpackPlugin({
      // 指定檢查文件的根目錄
      context: path.resolve(__dirname, "../src"),
    }),
    new HtmlWebpackPlugin({
      // 以 public/index.html 為模板創(chuàng)建文件
      // 新的html文件有兩個特點:1. 內(nèi)容和源文件一致 2. 自動引入打包生成的js等資源
      template: path.resolve(__dirname, "../public/index.html"),
    }),
    // 提取css成單獨文件
    new MiniCssExtractPlugin({
      // 定義輸出文件名和目錄
      filename: "static/css/main.css",
    }),
  // css壓縮
    new CssMinimizerPlugin(),
  ],
  // devServer: {
  //   host: "localhost", // 啟動服務(wù)器域名
  //   port: "3000", // 啟動服務(wù)器端口號
  //   open: true, // 是否自動打開瀏覽器
  // },
  mode: "production",
};

vue.config.js 和 webpack.config.js差別

以下為vue項目中實際使用的vue.config.js配置文件

const httpUrl = "www.baidu.com";
// const path = require("path");
const os = require("os");
function getNetworkIp() {
  let needHost = ""; // 打開的host
  try {
    // 獲得網(wǎng)絡(luò)接口列表
    let network = os.networkInterfaces();
    for (let dev in network) {
      let iface = network[dev];
      for (let i = 0; i < iface.length; i++) {
        let alias = iface[i];
        if (
          alias.family === "IPv4" &&
          alias.address !== "127.0.0.1" &&
          !alias.internal
        ) {
          needHost = alias.address;
        }
      }
    }
  } catch (e) {
    needHost = "localhost";
  }
  return needHost;
}
module.exports = {
  publicPath: "./",
  outputDir: "./dist",
  lintOnSave: false,
  // webpack-dev-server 相關(guān)配置
  devServer: {
    open: true,
    // host: "192.168.101.167",
    host: getNetworkIp(),
    port: 8088,
    https: false,
    hotOnly: false,
    //設(shè)置代理
    proxy: {
      "/api": {
        target: httpUrl,
        changeOrigin: true,
        pathRewrite: {
          "^/api": "/",
        },
      },
    },
  },
  // 第三方插件配置
  pluginOptions: {},
  // webpack相關(guān)配置
  chainWebpack: (config) => {
    config.resolve.alias
      .set("vue$", "vue/dist/vue.esm.js")
      .set("@", path.resolve(__dirname, "./src"));
  },
  // css相關(guān)配置
  css: {
    // 是否分離css(插件ExtractTextPlugin)
    extract: true,
    // 是否開啟 CSS source maps
    sourceMap: false,
    // css預(yù)設(shè)器配置項
    loaderOptions: {},
    // 是否啟用 CSS modules for all css / pre-processor files.
    modules: false,
  },
};

區(qū)別

vue-cli2.0時代,webpack的配置文件寫在config/index.js 文件
vue-cli3.0時代,沒了config文件夾,vue.config.js寫在項目的根目錄下

  • webpack.config.js是webpack的配置文件,所有使用webpack作為打包工具的項目都可以使用,vue的項目可以使用,react的項目也可以使用。
  • vue.config.js是vue項目的配置文件,專用于vue項目。通過vue.config.js中常用功能的配置,簡化了配置工作,當(dāng)然如果需要更專業(yè)的配置工作,webpack.config.js和vue.config.js在vue項目中是可以并存的。

項目中主要做了哪些配置

配置多環(huán)境變量
配置基礎(chǔ)的vue.config.js
配置 proxy 代理
配置別名
添加IE兼容
開啟gzip壓縮

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容