webpack指南

从零开始使用webpack搭建项目开发环境

Posted by page on July 18, 2022

webpack指南

前言

webapck干什么?

依赖打包(主要),即根据资源依赖的分析后进行处理,输出结果;文件处理(次之);

为什么要对资源打包?

功能逐渐复杂推动引入大量其它类库,团队成员按照功能划分协作开发项目这两大现象;项目愈加需要合理组织代码,否则无法持续开发或维护;出现模块化开发,这时各种模块化规范用于规定模块独立的标准;

但多模块导致项目文件增加,导致http请求数增加;且随着模块数增加,依旧存在依赖关系逐渐复杂影响开发的问题;推动打包工具,代码在开发环境是按功能划分模块,开发体验良好;经过webpack分析模块依赖,打包输出为优化后的生产环境资源部署在服务器;

概念

chunk module bundle

module : 开发环境下引用的资源;

chunk : webpack文件打包处理的单位;

bundle :最终输出的资源文件;

代码类型

app:你或团队写的项目代码;

vendor/library:依赖的第三方的 library 或 “vendor” 代码;

runtime/manifest:webpack打包过程中,各个模块之间的信息以及关联关系记录在manifest 数据集合中;runtime 根据 manifest 数据管理模块代码,包含了所有模块之间的交互时,连接模块所需的加载和解析逻辑(已经加载到浏览器中的连接模块逻辑,以及尚未加载模块的延迟加载逻辑);

起始

  1. 初始化项目

    新建 admin 项目根目录,执行 npm init -y 初始化项目,删除入口 "main": index.js ,添加 "private": true

  2. 安装 webpack 与命令行

    npm i webpack webpack-cli -D
    
  3. 基本项目文件

    新建 build/webpack.config.js ,添加打包命令 "build": webpack --config ./build/webpack.config.js

    新建 scr/main.js 入口文件;

    安装 html-webpack-plugin 插件,新建 public/index.html 作为html模板;

  4. 编写打包配置

    尝试 npm run build

    // webpack.config.js
    const path = require('path');
    const resolve = (filePath) => path.resolve(__dirname,'../',filePath);
       
    // depend plugins
    const HtmlWebpackPlugin = require("html-webpack-plugin");
       
    moudle.exports = {
      mode: "production",
      entry: resolve('./src/main.js'),
      output: {
        path: resolve('./dist')
        filename: 'QManager.bundle.js'
      },
      plugins: [
        new HtmlWebpackPlugin({
          template: resolve('./public/index.html')
        })
      ]
    }
    

开发环境

  1. 安装开发工具

    npm i webpack-dev-server -D
    
  2. 添加打包命令

    "dev": "webpack serve --config ./build/webpack.config.js --open",
    "serve": "webpack serve --config ./build/webpack.config.js --open",
    
  3. 开发环境配置

    module.exports = {
      mode: "development",
      // mode: "production",
      devtool: 'cheap-module-eval-source-map',
      // devtool: 'hidden-source-map',
      devServer: {
        static: resolve('./dist')
      }
    }
    

分离配置

  1. 安装 webpack-merge 插件:npm i webpack-merge -D

  2. 分别新建 webpack.common.jswebpack.dev.jswebpack.prod.js ,分离出对应通用配置、开发环境配置、生产环境配置

  3. 调整各环境运行命令

    "dev": "webpack serve --config ./build/webpack.dev.js --node-env development",
    "serve": "webpack serve --config ./build/webpack.dev.js --node-env development",
    "build": "webpack --config ./build/webpack.prod.js --node-env production"
    

Loader

加载CSS

css-loader:将 .css 转换成CommonJs模块,css存在于JS模块中(包括图片、字体);

style-loader:JS字符串生成为 style 节点作用于页面;

MiniCssExtractPlugin.loader:支持将chunk中css单独输出为文件;

module: {
  rules: [
    // 生产环境下,推荐使用MiniCssExtractPlugin.loader替代style-loader
    { test: /\.css$/, use: ["style-loader", 'css-loader'] },
  ]
}

加载Sass

npm i sass sass-loader -D
rules: [
  { test: /\.css$/, use: ["style-loader", "css-loader"] },
  { test: /\.s[ac]ss$/, use: ["style-loader", "css-loader", "sass-loader"]},
  ...
]
// 全局注入scss代码
{
  test: /\.s[ac]ss$/,
  use: [
    "style-loader",
    "css-loader",
    {
      loader: "sass-loader",
      options: {
        additionalData: (content) => {
          const additionalData = `
            @import "~@/style/variables.scss";
            $env: "${process.env.NODE_ENV}";
            $staticUrl: "${process.env.VUE_APP_STATIC_URL}";
          `;
          return additionalData + content;
        }
      }
    }
  ]
},

配置别名

  resolve: {
    alias: {
      "@": resolve("src"),
      "@assets": resolve("src/assets"),
      "@components": resolve("src/components"),
      "@views": resolve("src/views"),
    },
    // 后缀名解析顺序
    extensions: [".js", ".json", ".wasm", ".vue"]
  }

主流框架

Vue

  1. 安装加载器与编译插件:npm i vue-loader@next @vue/compiler-sfc -D

  2. 安装 vuenpm install vue@next

  3. 添加加载器与插件配置

    // loaders
    const { VueLoaderPlugin } = require('vue-loader');
       
    module.exports = {
      module: {
        rules: [
          { test: /\.vue$/, loader: 'vue-loader' }
        ]
      },
      plugins: [ new VueLoaderPlugin() ]
    }
    
  4. 创建Vue实例

    import { createApp } from 'vue';
    import App from './App.vue';
       
    createApp(App).mount('#app') 
    

Eslint

  1. 安装

    npm i eslint eslint-webpack-plugin -D
    
  2. .eslintrc.js 文件配置

  3. 引入插件

    const ESLintPlugin = require('eslint-webpack-plugin');
       
    module.exports = {
      // ...
      plugins: [
        new ESLintPlugin()
        // ...
      ]
    };
    

Babel

  1. 安装

    npm i @babel/core @babel/preset-env babel-loader -D
    
  2. 引入loader

    {
      test: /\.js$/,
      exclude: /node_modules/,
      use: {
        loader: "babel-loader",
        options: { cacheDirectory: true }, // 开启缓存
      },
    }
    
  3. babel.config.json 配置 与 构建目标 .browserslistrc 配置