webpack工具介绍


webpack核心概念

Entry

入口,指定webpack入口文件,从该文件开始打包;

Output

输出,打包文件输出名称及路径

Loader

支持webpack处理非js文件

Plugins

插件,支持webpack执行范围更广的任务,包括打包优化、压缩、定义变量等;

Module

配置webpack打包模式

webpack安装模块:

yarn add webpack webpack-cli html-webpack-plugin  webpack-dev-server css-loader style-loader less-loader mini-css-extract-plugin  css-minimizer-webpack-plugin csv-loader xml-loader  yaml toml

工具安装后需手工在项目根目录下创建配置文件:webpack.config.js

可根据生产及开发环境生成对应配置文件:

  • 开发环境: webpack.config.dev.js,保留entry、output、module、mode、plugins、devtool、devServer
  • 生产环境:webpack.config.prod.js,保留entry、output, module ,mode,plugins,optimization

可通过提取公共配置降低重复工作:

// 通用配置提取到webpack.config.common.js,格式与webpack.config.js保持一致

// 全局安装webpack-merge插件进行合并

const {merge} = require('webpack-merge')

const commonConfig = require('./webpack.config.common.js')

const devConfig = require('./webpack.config.dev.js')
const prodConfig = require('./webpack.config.prod.js')

module.exports = (env) => {
	switch (true) {  
  case env.development === "development":  
    return merge(commonConfig, devConfig);  
 case env.production === "production":  
    return merge(commonConfig, prodConfig);  
 default:  
    return new Error("No matching configuration was found");  
}
}

npx webpack -c webpack.config.dev.js

const path = require('path')  
const HtmlWebpackPlugin = require('html-webpack-plugin')  
const MiniCssextractPlugin = require('mini-css-extract-plugin')  
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')  
const TerserPlugin = require('terser-webpack-plugin')  
const webpack = require('webpack')  
const yaml = require('yaml')  
  
module.exports = (env) => {  
  return {  
    entry: {  
      // 方案一,单入口模式  
 // index: './src/main.js', // 指定源码入口文件名 // 多入口模式 /* index: { import: './src/index.js', dependOn: 'shared', }, another: { import: './src/other.js', dependOn: 'shared', }, // 其他入口文件名 shared: 'lodash', // 指定多入口共享模块打包至shared.js文件中 */  
 // 方案三, 使用webpack插件 抽离公共模块 配置在optimize中  
 index: './src/main.js',  
 another: './src/other.js',  
 },  
 output: {  
      filename: '[name].[contenthash].js', // 指定打包文件名,浏览器缓存时会根据文件名判断是否变更,建议使用名称加contenthash方式生成文件名  
 path: path.resolve(__dirname, './dist'), // 指定打包路径  
 clean: true, // 自动清空打包目录  
 assetModuleFilename: 'images/[contenthash][ext]',  
 publicPath: 'http://localhsot:8080/', // 指定打包后引用资源路径前缀  
 pathinfo: false, // 编译代码中不包含路径信息  
 },  
  
 // 可选为 none, development及 production  
 mode: env.production ? 'production' : 'development',  
  
 resolve: {  
      // 配置路径别名  
 alias: {  
        '@': path.resolve(__dirname, './src'),  
 },  
  
 // 按顺序默认识别扩展名  
 extensions: ['.js', '.vue', '.json'],  
 },  
  
 externalsType: 'script', // 指定cdn模块以什么方式暴露  
 // 指定CDN模块,不会进行打包 
externals: {  
      jquery: ['https://cdn.bootcdn.net/ajax/libs/jquery/3.6.0/jquery.js', 'jQuery'],  
 },  
  
 plugins: [  
      // 指定使用插件打包文件  
 new HtmlWebpackPlugin({  
        template: './index.html', // 使用源文件作为模板  
 filename: 'app.html', // 打包后文件名  
 inject: 'body', // js插入标签路径  
 }),  
 new MiniCssextractPlugin({  
        filename: 'style/[contenthash][.ext]', // 配置css抽离生成的文件路径及文件名  
 }),  
  
 // 配置全局变量  
 new webpack.ProgressPlugin({  
        _: 'axios',  
 }),  
 ],  
  
 module: {  
      rules: [  
        // 全局导出  
 {  
          test: require.resolve('./src/main.js'),  
 use: 'exports-loader?type=commonjs&exports=file,multiple|helpers.parse|parse',  
 },  
  
 {  
          test: /\.png$/, // 打包png后缀文件  
 type: 'asset/resource', // 作为资源打包至assets目录  
 generator: {  
            filename: './dist/images/[contenthash][ext]', // 优先 指定打包文件路径、文件名及后缀名  
 },  
 },  
 {  
          test: /\.svg$/, // 打包svg扩展名文件  
 type: 'asset/inline', // 将资源文件打包成base64信息至代码文件中  
 },  
 {  
          test: /\.txt$/, // 打包txt扩展名文件  
 type: 'asset/source', // 将资源文件直接打包至代码文件中  
 },  
 {  
          test: /\.jpg$/, // 打包jpgt扩展名文件  
 type: 'asset', // 通用资源类型,自动选择创建为resource或inline,根据资源大小自动选择,默认为8k以下inline  
 // 自定义临界值 parser: {  
            dataUrlCondition: {  
              maxSize: 4 * 1024 * 1024, // 临界值修改为4Mb  
 },  
 },  
 },  
 {  
          test: /\.(css|less)$/,  
 use: ['style-loader', 'css-loader', 'less-loader'], // 使用指定loader对对应资源进行解析并打包  
 },  
 {  
          test: /\.(css|less)$/,  
 use: [MiniCssextractPlugin.loader, 'css-loader', 'less-loader'], // 将所有样式文件抽离合并为一个样式文件,并超链接至代码文件中  
 },  
 {  
          test: /\.(woff|woff2|eot|ttf|otf)$/,  
 type: 'asset/resource', // resource支持加载任意类型资源  
 },  
 {  
          test: /\.(tsv|csv)$/,  
 use: 'csv-loader', // 使用loader加载csv/tsv数据,转换为数组  
 },  
 {  
          test: /\.xml$/,  
 use: 'xml-loader', // 使用loader加载xml数据  
 },  
  
 {  
          test: /\.yaml$/, // 自定义json模块的parser  
 type: 'json',  
 parser: {  
            parse: yaml.parse,  
 },  
 },  
 {  
          test: /\.js$/,  
 exclude: /node_modules/, // 排除node_modules文件下下js文件加载  
 use: {  
            loader: 'babel-loader', // 指定loader加载js  
 option: {  
              presets: ['@babel/preset-env'], // 使用指定插件集合加载js  
 plugins: [['@babel/plugin-transform-runtime']], // 兼容 async/await语法  
 },  
 },  
 },  
 // 配置webpack集成eslint语法规范  
 {  
          test: /\.(js|vue)$/,  
 use: ['babel-loader', 'eslint-loader'],  
 },  
 ],  
 },  
  
 optimization: {  
      minimizer: [  
        new CssMinimizerPlugin(), // 需配合mode:production  压缩加载的CSS文件  
 new TerserPlugin(), // 启用打包代码压缩  
 ],  
  
 // 配合entry 方案三使用  
 splitChunks: {  
        // chunks: 'all',  
 cacheGroups: {  
          test: /[\\/]node_modules[\\/]/, // 以固定名称缓存第三方模块  
 name: 'vendors',  
 chunks: 'all',  
 },  
 },  
 usedExports: true, // 启用treeshaking  
 },  
  
 // 启用source-map,可直接查看源文件报错位置  
 devtool: 'inline-source-map',  
  
 devServer: {  
      static: './dist',  
 compress: true, // 启动压缩  
 port: 3000, // 指定服务启动端口  
 headers: {  
        'X-Access-Token': 'abc123', // 添加token到响应头  
 },  
  
 proxy: {  
        '/api': 'http://localhost:9000', // 解决跨域访问问题  
 },  
 http2: true, // 启用https 或者直接使用https:true  需自行配置证书  
  
 historyApiFallback: true, // 解决spa路由刷新可能报错  
 host: '0.0.0.0', // 允许局域网访问  
 hot: true, // 开启模块热替换 HMR  
 liveReload: true, // 开启模块热加载  
  
 // 禁止devServer页面eslint错误提示覆盖层 client: {  
        overlay: false,  
 },  
 },  
 }  
}

npx webpack 自动寻找项目内webpack命令路径并执行

npx webpack –watch 自动检测文件变化并重新打包

npx webpack-dev-server –open 启动dev-server

babel-loader

babel-loader用于将js代码加载为向下兼容模式
安装插件

yarn add babel-loader  @babel/core  @babel/preset-env  @babel/runtime  @babel/plugin-transform-runtime terser-webpack-plugin -D
  • babel-loader: 在webpack中应用babel解析ES6的桥梁
  • @babel/core:babel核心代码
  • @babel/preset-env:babel预设,一组babel插件的集合
  • @babel/runtime:兼容async/await语法
  • @babel/plugin-transform-runtime:按需调用runtime

regeneratorRuntime: 是webpack打包生成的全局辅助函数,由babel生成,用于兼容async/await语法

webpack好处

代码分离,提升加载速度
分离方法:

  • 入口手动分离
  • 动态加载
    • 懒加载
    • 预获取/预加载
      • prefetch: 预获取,在页面加载完成后,利用空闲资源进行文件加载
      • preload:预加载,
//在需要代码分离引入的模块前添加注解,可指定代码分离后文件名
import(/*webpackChunkName: 'math', webpackPrefetch: true*/ './utils/abc.js')

package.json

该配置文件可通过npm init自动生成,该文件结构为:

{  
  "name": "frontend",  
 "version": "0.1.0",  
 "private": true,  
// 定义npm run xxx脚本命令
 "scripts": {  
   "serve": "vue-cli-service serve",  
	 "build": "vue-cli-service build",  
	 "lint": "vue-cli-service lint"  
 },  

// 业务依赖模块
 "dependencies": {  
    "axios": "^0.24.0",  
		"bcryptjs": "^2.4.3",  
		"core-js": "^3.6.5",  
		"dateformat": "^5.0.2",  
		"element-ui": "^2.15.6",  
		"jsonwebtoken": "^8.5.1",  
	  "vue": "^2.6.11",  
	  "vue-clipboard2": "^0.3.3",  
	  "vue-router": "^3.5.3",  
	  "xlsx": "^0.17.4"  
 },  

//  开发依赖模块
 "devDependencies": {  
    "@babel/core": "^7.16.7",  
	 "@babel/plugin-transform-runtime": "^7.16.7",  
	 "@babel/preset-env": "^7.16.7",  
	 "@babel/runtime": "^7.16.7",  
	 "@vue/cli-plugin-babel": "~4.5.0",  
	 "@vue/cli-plugin-eslint": "~4.5.0",  
	 "@vue/cli-service": "~4.5.0",  
	 "babel-eslint": "^10.1.0",  
	 "babel-loader": "^8.2.3",  
	 "babel-plugin-component": "^1.1.1",  
	 "compression-webpack-plugin": "5.0.1",  
	 "css-loader": "^6.5.1",  
	 "css-minimizer-webpack-plugin": "^3.3.1",  
	 "csv-loader": "^3.0.3",  
	 "eslint": "7.30.0",  
	 "eslint-config-prettier": "^8.3.0",  
	 "eslint-config-standard": "^16.0.3",  
	 "eslint-plugin-import": "^2.25.4",  
	 "eslint-plugin-node": "^11.1.0",  
	 "eslint-plugin-prettier": "^4.0.0",  
	 "eslint-plugin-promise": "^6.0.0",  
	 "eslint-plugin-standard": "^5.0.0",  
	 "eslint-plugin-vue": "^6.2.2",  
	 "html-webpack-plugin": "^5.5.0",  
	 "less": "^4.1.2",  
	 "less-loader": "7.3.0",  
	 "mini-css-extract-plugin": "^2.4.6",  
	 "prettier": "^2.5.1",  
	 "style-loader": "^3.3.1",  
	 "terser-webpack-plugin": "^5.3.0",  
	 "toml": "^3.0.0",  
	 "vue-style-loader": "^4.1.3",  
	 "vue-template-compiler": "^2.6.11",  
	 "webpack": "^5.65.0",  
	 "webpack-cli": "^4.9.1",  
	 "webpack-dev-server": "^4.7.2",  
	 "xml-loader": "^1.2.1",  
	 "yaml": "^1.10.2"  
 },  
 "eslintConfig": {  
    "root": true,  
 "env": {  
      "node": true  
 },  
 "extends": [  
      "plugin:vue/essential",  
 "eslint:recommended"  
 ],  
 "parserOptions": {  
      "parser": "babel-eslint"  
 },  
 "rules": {}  
  },  
 "browserslist": [  
    "> 1%",  
 "last 2 versions",  
 "not dead"  
 ]  
}

eslint

语法规范工具

{
	// 配置支持运行环境
	"env": {
			"browser": true,  // 支持浏览器  
			"es2021": true    // 支持es2021
	},

	"extends": ["airbnb-base"], // 使用规则标准

	"parserOptions": {
			"ecmaVersion": 12,   //ecma版本
			"sourceType": "module"  //检查类型
	},

	// 配置自定义校验规则
	"rules": {
		
	}

	// 配置全局变量
	"globals": {
		
	}
}

eslint集成webpack

插件依赖

yarn add webpack webpack-cli webpack-dev-server html-webpack-plugin babel-loader eslint-loader @babel/core -D

webpack.config.js配置

module: {
	rules: [
		{
			test: /\.js$/,
			use: ['babel-loader', 'eslint-loader']
		}
	]
}

githooks & husky

git在仓库根目录下存在一个.git 隐藏文件,其子目录hooks内提供了一系列样例文件,以.sample结尾,对其重命名,去掉.sample后缀名则生效,文件名不能修改;
例如: pre-commit.sample为提交前运行钩子,去除后缀名后生效,作为用执行git commit前自动执行其内命令;

自定义githooks路径 : git config core.hooksPath xxx

husky

模块安装

yarn  add huskey -D

npx husky install  # 在项目下创建一个隐藏文件夹 .husky

# 创建钩子
npx husky add .husky/pre-commit 'XXX'

模块

import  a from './a'   // ES6语法

const a = require('./a')  // commonJs语法

模块解析

tree shaking

在webback.config.js中优化配置项中启用

sideEffects

sideEffects在package.json文件中
指定哪些文件是具有副作用的,tree shaking不应该删除

sideEffects: ['.global.css']   //指定不删除global.css结尾的文件

[[Webpack项目打包配置案例]]
[[Rollup打包工具]]
[[ESLINT与PRETTIER]]


文章作者: Semon
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Semon !
评论
  目录