NipGeihou's blog NipGeihou's blog
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档

NipGeihou

我见青山多妩媚,料青山见我应如是
  • Java

    • 开发规范
    • 进阶笔记
    • 微服务
    • 快速开始
    • 设计模式
  • 其他

    • Golang
    • Python
    • Drat
  • Redis
  • MongoDB
  • 数据结构与算法
  • 计算机网络
  • 应用

    • Grafana
    • Prometheus
  • 容器与编排

    • KubeSphere
    • Kubernetes
    • Docker Compose
    • Docker
  • 组网

    • TailScale
    • WireGuard
  • 密码生成器
  • 英文单词生成器
🍳烹饪
🧑‍💻关于
  • 分类
  • 标签
  • 归档
  • nodejs

  • css

  • 最佳实践

  • TypeScript

  • ajax

  • JavaScript

  • 前端工程化

    • Node.js
    • 软件包管理器
    • webpack
      • 定义
      • 打包
        • 入口与出口
      • 打包HTML
      • 打包CSS代码
        • 优化-提取CSS代码
        • 优化压缩
      • 打包less代码
      • 打包图片
      • 开发环境
      • 环境变量
        • 打包场景应用
        • 前端注入环境变量
        • 开发环境调错
      • 解析别名
      • 优化CDN
    • vite
  • React

  • nextjs

  • Flutter

  • 笔记

  • 前端
  • 前端工程化
NipGeihou
2024-08-10
目录

webpack

# 定义

静态模块打包工具

静态模块:指的是编写代码过程中的,html、css、js、图片等固定内容的文件

打包:把静态模块内容压缩,整合,转译等(前端工程化)

  • 把 less/sass 转成 css 代码
  • 把 ES6 + 降级成 ES5
  • 支持多种模块标准语法

# 打包

  • 准备一个要打包的 util 包
  • 安装 webpack
npm i webpack webpack-cli --save-dev # -save-dev 仅开发时使用,对应到package.json的devDependencies
  • package.json 配置打包命令
...
  "scripts": {
    "build": "webpack",
  },
...
npm run build # 打包,生成dist文件

# 入口与出口

/webpack.config.js

const path = require('path');

module.exports = {
  entry: './path/to/my/entry/file.js',  // 打包的入口:即源代码执行开始的文件(index.js)
  output: {
    path: path.resolve(__dirname, 'dist'),  // 打包的出口:输出的目录,默认dist
    filename: 'my-first-webpack.bundle.js',  // 输出目录的入口文件(main.js)
    clean: true, // 打包前清空输出目录
  },
};

# 打包 HTML

HtmlWebpackPlugin | webpack 中文文档 (opens new window)

在打包时生成 html 文件

安装

npm install --save-dev html-webpack-plugin

/webpack.config.js 引入

 








 
 
 
 
 
 


const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');

module.exports = {
  entry: 'index.js',
  output: {
    path: path.resolve(__dirname, './dist'),
    filename: 'index_bundle.js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, 'public/login.html'), // 模板文件
      filename: path.resolve(__dirname, 'dist/login/index.html'), 输出文件
    })
  ]
};

# 打包 CSS 代码

Loaders | webpack 中文文档 (opens new window)

默认 webpack 只支持 js

  • css-loader:css-loader 会对 @import 和 url() 进行处理,就像 js 解析 import/require() 一样
  • style-loader:把 CSS 插入到 DOM 中

Install

npm install --save-dev css-loader style-loader # 默认最新版,需要与webpack版本一致

入口文件(index.js)

// bootstrap
import 'bootstrap/dist/css/bootstrap.min.css'  // npm i bootstrap

import css from 'file.css';  // 引入样式
import './file.css';   // 当前文件没有使用到,也可以不设别名,这些import只是让webpack能识别到

/webpack.config.js 引入

module.exports = {
  module: {
    rules: [
      {
        test: /\.css$/i,  // 匹配所有的css文件
        use: ['style-loader', 'css-loader'],  // 逆序执行,从后往前执行
      },
    ],
  },
};

# 优化 - 提取 CSS 代码

webpack-contrib/css-loader: CSS Loader (opens new window)

MiniCssExtractPlugin | webpack 中文文档 (opens new window)

上述操作后,css 样式是存储在 js 文件中的,不利于缓存;

使用 mini-css-extract-plugin 插件

Install

npm install --save-dev mini-css-extract-plugin

入口文件(index.js)

同上

/webpack.config.js 引入

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  plugins: [new MiniCssExtractPlugin()], // 引入插件
  module: {
    rules: [
      {
        test: /\.css$/i,
        // use: ['style-loader', 'css-loader'],   // 不用和style-loader一起使用
        use: [MiniCssExtractPlugin.loader, "css-loader"], // 配置规则,配合css-loader
      },
    ],
  },
};

最终打包时样式生成在 main.css

# 优化压缩

CssMinimizerWebpackPlugin | webpack 中文文档 (opens new window)

上一步生成的 main.css 并没有压缩

Install

npm install css-minimizer-webpack-plugin --save-dev

/webpack.config.js import


 










 
 
 
 
 
 
 
 


const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin');

module.exports = {
  module: {
    rules: [
      {
        test: /.s?css$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
    ],
  },
  optimization: {
    minimizer: [
      // 在 webpack@5 中,你可以使用 `...` 语法来扩展现有的 minimizer(即 `terser-webpack-plugin`),将下一行取消注释(保证JS代码还能被压缩处理)
      `...`, // 引入原有的压缩插件,否则原有的会失效,js变成不压缩的
      new CssMinimizerPlugin(),
    ],
  },
  plugins: [new MiniCssExtractPlugin()],
};

# 打包 less 代码

less-loader | webpack 中文文档 (opens new window)

与 css 代码同理

# 打包图片

资源模块 | webpack 中文文档 (opens new window)

无需下载额外的加载器,webpack5 已内置。

默认情况下,当图片大于 8KB 时,打包图片到静态资源(dist/assets),反之使用 data URI(base64)

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    filename: 'main.js',
    path: path.resolve(__dirname, 'dist')
  },
  module: {
    rules: [
      {
       test: /\.(png|jpg|gif)$/i,
       type: 'asset',
       generator: {
         filename: 'static/[hash][ext][query]' // hash 文件的哈希值;query查询参数 ?key=xxx
       }
      }
    ]
  },
};

# 开发环境

开发环境 | webpack 中文文档 (opens new window)

启动 WEB 服务,自动检测代码,热更新

Install

npm install --save-dev webpack-dev-server

/webpack.config.js import

 const path = require('path');
 const HtmlWebpackPlugin = require('html-webpack-plugin');

 module.exports = {
+   mode: 'development', // 开发模式:调试代码、实时加载,模块热替换等
-   mode: 'production', // 生产模式:压缩代码、资源优化、更轻量等
   entry: {
     index: './src/index.js',
     print: './src/print.js',
   },
   devtool: 'inline-source-map',
+  devServer: {
+    static: './dist',  // 放在内存,设不设置都无所谓
+  },
   plugins: [
     new HtmlWebpackPlugin({
       title: 'Development',
     }),
   ],
   output: {
     filename: '[name].bundle.js',
     path: path.resolve(__dirname, 'dist'),
     clean: true,
   },
+  optimization: {
+    runtimeChunk: 'single',
+  },
 };

package.json

...
   "scripts": {
    "dev": "webpack serve --open", // --open自动打开默认浏览器
   }
...
npm run dev

笔记

切换开发模式的两种方法:

  1. /webpack.config.js 中修改 mode
  2. /package.json 的启动脚本中添加 --mode=development

# 环境变量

# 打包场景应用

在打包 CSS 代码中提及 style-loader 和 MiniCssExtractPlugin.loader 两种加载器,并且两者是互斥的。在开发环境中使用 style-loader 加载器有更好的性能表现,而在生产环境则 MiniCssExtractPlugin.loader 更佳。

使用 cross-env 软件包可以灵活的在不同环境下切换两种加载器

Install

npm i cross-env --save-dev

package.json

...
   "scripts": {
  "build":"cross-env NODE_ENV=production webpack --mode=production",
  "dev": "cross-env NODE_ENV=development webpack serve --open --mode=development", // --open自动打开默认浏览器
}
...

/webpack.config.js 引入

const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  plugins: [new MiniCssExtractPlugin()], // 引入插件
  module: {
    rules: [
      {
        test: /\.css$/i,
        // use: ['style-loader', 'css-loader'],   // 不用和style-loader一起使用
        use: [process.env.NODE_ENV === 'development' ? 'style-loader': MiniCssExtractPlugin.loader, "css-loader"], // 配置规则,配合css-loader
      },
    ],
  },
};

# 前端注入环境变量

DefinePlugin | webpack 中文文档 (opens new window)

上面的 cross-env 只能在 node.js 环境下生效,前端代码无法访问 process.env.NODE_ENV

内置插件,无需安装

/webpack.config.js 引入

...
plugins: [
+    new webpack.DefinePlugin({
+      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV),
+    });
]
...

之后就可以在前端 js 中使用 process.env.NODE_ENV

index.js

if(process.env.NODE_ENV === 'production'){
    console.log = function(){} // 生产模式下不打印log
}

# 开发环境调错

默认情况下,由于代码压缩,无法在控制台直观找到错误发生的行数。

/webpack.config.js 引入

const config = {...}

+ if(process.env.NODE_ENV === 'development'){
+    config.devtool = 'inline-source-map'	// 仅开发模式使用
+ }

module.exports = config

# 解析别名

解析 (Resolve) | webpack 中文文档 (opens new window)

/webpack.config.js 引入

const config = {
	...
+	  resolve: {
+        alias: {
+          '@': path.resolve(__dirname, 'src'),
+        },
+      },
	...
}


module.exports = config

index.js

- import youAxios from '../src/utils/requst.js'
+ import youAxios from '@/utils/requst.js'

# 优化 CDN

以前的服务器带宽小,会有优势,现在意义不大,现在更主流的是用自己的 CDN 资源。

index.html

<% if(htmlWebpackPlugin,option.useCDN){} %>
    <link hre="https://cdn.....min.css">
<% } %>

/webpack.config.js import

const config = {
    ...
    new HtmlWebpackPlugin({
      ...
      useCdn: process.env.NODE_ENV === 'development'
      ...
    })
    ...
}

if(process.env.NODE_ENV === 'production'){
    config.externals = {
        // key: import from 语句后面的字符串
        // value: 留在原地的全局变量(最好和cdn在全局暴雷的变量一致)
        // import 'bootstrap/dist/css/bootstrap.min.css'
		'bootstrap/dist/css/bootstrap.min.css' : 'bootstrap'
        // import 'axios'
        'axios' : 'axios'
	 }
}

module.exports = config
上次更新: 2024/08/12, 01:58:39
软件包管理器
vite

← 软件包管理器 vite→

最近更新
01
Docker Swarm
04-18
02
安全隧道 - gost
04-17
03
Solana最佳实践
04-16
更多文章>
Theme by Vdoing | Copyright © 2018-2025 NipGeihou | 友情链接
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式