了解webpack基本配置,通过webpack配置Vue项目。

前言

webpack是一个模块打包工具(module bundler),它可以对Web前端和Node.js等应用进行打包。

了解webpack基本配置

安装webpack

首先 我们需要通过包管理工具(npm/pnpm/yarn等)来安装webpack所需要的包(webpackwebpack-cli), 这是最基本的文件。

shell 复制代码
npm install webpack webpack-cli -D 
// webpack为webpack的核心包,webpack-cli是webpack的命令行工具,运行webpack命令需要使用
//可以通过@来安装指定版本 如:webpack@5.21.2

webpack相关基本配置

介绍webpack的相关配置,详细可参考下文中的webpack.config.js示例。

context

基础目录,表示资源入口entry是以哪个目录为起点的。值为字符串,表示一个绝对路径。

entry

webpack打包的入口文件配置项。表示从哪个文件为入口开始打包。值可以为字符串,也可以为数组、对象、函数、描述符。

  • 字符串形式:最简单的形式,表示打包入口的js文件。
  • 数组形式:最后一个文件是资源的入口文件,数组的其余文件会被预先构建到入口文件中。(注:数组形式的entry本质上还是单一入口。)
  • 对象形式:对象形式的entry又被称为多入口配置,与前两项不同,多入口文件配置打包后生成多个JS文件。
  • 函数形式:函数形式取函数返回值作为入口配置,返回值为上述三项之一。可以做一些额外的逻辑处理,但搭脚手架时很少使用。
  • 描述符形式:描述符形式也是一个对象,米哦啊书夫语法可以用来给入口传入额外的选项,例如设置dependOn选项时,可以与另一个入口chunk共享模块。

output

webpack打包后的资源出口配置项,四个属性:"path"(输出路径)、"filename"(输出文件名),"publicPath","chunkFilename"。

  • filename:打包后生成的资源名称,可以是文件名称,也可以是相对地址('./js/bundle.js')。最终打包输出的文件地址时path绝对路径与filename拼接后的地址。支持生成动态文件名如:'[hash]-bundle.js'。
  • path:表示资源打包后输出的位置,需要一个绝对路径,默认为dist目录。
  • publicPath:资源访问路径,默认值为auto。
  • chunkFailename:表示打包过程中非入口文件的chunk名称,通常在使用异步模块的时候,会生成非入口文件的chunk。

动态值

补充 :关于动态值有hash、fullhash、chunkhash、contenthash,与浏览器缓存相关,对于一些长期不变更的文件资源,通常会存储在本地磁盘,当文件变动时再去请求新的文件,而这种动态值如hash、chunkhash、contenthash是根据文件内容计算出来的,通过动态值得变化来判断文件有无变更。通常通过结合name(名字)、id(唯一序列号)来使用。 目前fullhash已经替代hash,使用hash会出现警告。
区别:

  • 通常对于单文件我们使用hash(fullhash)即可。例如:[name]-[fillhash:8].js,hash是根据全部参与打包得文件计算出来的。
  • 对于多文件通常使用chunkhash。chunkhash是通过当前打包的chunk计算出来的。
  • 对于css文件,我们一般使用contenthash。主要用于计算css得hash值。

mode

webpack打包模式,有三种分别为"production"(默认值),"development","none",productiondevelopment这两种模式分别按照线上生产和本地测试做一些优化处理。其中production是给生产环境打包使用(压缩代码),none会保留原始的打包结果。

预处理器

Loader:预处理器本质上是一个函数,它接收一个资源模块,然后将其处理成webpack能使用的形式。(解析模板),配置项为module

常用的一些预处理器:style-loadercss-loadervue-loaderts-loaderfile-loaderurl-loaderbabel-loadersass-loader等。 预处理配置项:exclude/include,通过字符串或正则表达式匹配文件,排除或进行处理。exclude优先级高。

插件

插件与预处理器不同,预处理器主要用来解析模板的,而插件是扩展wbepack的能力的。配置项为plugins

常用插件有:clean-webpack-plugincopy-webpack-pluginhtml-webpack-pluginmini-css-extract-pluginterser-webpack-pluginwebpack-bundle-analyzer等。

webpack本地服务

webpack官方提供了一个webpack服务工具webpack-dev-server,在本地开启一个网络服务器,可以用来处理网络请求。通过npm安装,npx启动服务。

shell 复制代码
    npm install webpack-dev-server -D
    npx webpack-serve 

webpack-dev-server常见配置,通过在webpack配置文件的devServer里来进行配置。

js 复制代码
······
    devServer:{
        histroyApiFallback:true, //解决Html Histroy模式下 所有404重定向问题。
        publicPath:'/',  //服务器请求资源路径,默认值为'/'
        open:true, //启动服务后是否自动打开浏览器
        compress:true,  // 是否为静态资源开启Gzip压缩
        hot:false, //是否启动热替换功能
        port:8080, // 服务端口号设置
    }
······

环境变量

这里的环境指的是Node.js的环境变量,Node.js在执行JS代码是可以获取到环境变量,它们存放在process.env模块中。 在实际开发中我们可以通过cross-env来设置环境变量。

shell 复制代码
    npm install cross-env -D

通过在package.json中配置如:

json 复制代码
   "script":{
       "start":"cross-env NODE_ENV=development webpack serve --config webpack.config.js"
       "build":"cross-env NODE_ENV=production webpack --config webpack.config.js"
   }

这样我们就可以通过不同命令来配置环境变量的值,并在webpack配置文件中使用。 当然我们还可以通过webpack自带插件,DefinePlugin来将环境变量注入到业务逻辑代码中。

js 复制代码
   plugins:[
       new wbepack.DefinePlugin({
       MY_DEV:'dev'
       })
   ]

webpack.config.js 示例

通常我们使用webpack都会在项目根目录下配置webpack.config.js文件,当我们执行webpack命令时,webpack会自动寻找该文件并根据其配置信息进行打包。 示例:

javascript 复制代码
    //webpack.config.js文件配置
    const path = require('path');
    const { CleanWebpackPlugin } = require('clean-webpack-plugin');
    const CopyPlugin = require('copy-webpack-plugin');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    module.exports={
        entry:'./a.js', //webpack入口文件
        output:{ //输出文件
            path:path.resolve(_dirname,'dist'), //输出文件路径
            filename:'bundle.js' //输出文件名
        },
        mode:'none' //webpack打包模式,有三种分别为"production"(默认值),"development","none"
        //production和development这两种模式分别按照线上生产和本地测试做一些优化处理。
        //其中production是给生产环境打包使用(压缩代码),none会保留原始的打包结果。
        module:{
            rules:[{
                test:'/\.(scss|css)$/',
                use:['style-loader','css-loader','sass-loader']
                // use:[MiniCssExtractPlugin.loader,'css-loader','sass-loader'] 生产
            },  
            {
                test: /\.vue$/, //解析vue 模板
                use: "vue-loader"
            },
            {
                test:/\.js$/,
                use:{
                    loader:'babel-loader',
                    options:{
                        presets:['@babel/preset-env']
                    }
                }
            },
            {
                test:/\.(png|jpg)$/,
                use:{
                    loader:'url-loader',
                    options:{
                        limit:1024*8,
                    }
                }
            }
            ]
        },
        plugins:[
            new CleanWebpackPlugin(),
            new CopyPlugin({
                patterns:[
                    {
                       from:path.resolve(_dirname,'src/img/'),
                       to:path.resolve(_dirname,'dist/image/')
                    },
                ]
            }),
            new MiniCssExtractPlugin({
                filename:'[name]-[contenthash:8].css',
                chunkFilename:'[id].css',
            })
            new HtmlWebpackPlugin({
                title:'webpack入门',
                filename:'index.html',
                // template:'./public/index.html'
            }),
            
        ],
        devServer:{
            histroyApiFallback:true, //解决Html Histroy模式下 所有404重定向问题。
            publicPath:'/',  //服务器请求资源路径,默认值为'/'
            open:true, //启动服务后是否自动打开浏览器
            compress:true,  // 是否为静态资源开启Gzip压缩
            hot:false, //是否启动热替换功能
            port:8080, // 服务端口号设置
        }
    }
//npm install webpack@5.21.2 webpack-cli@4.9.0 webpack-dev-server@3.11.2 -D

合并配置(开发环境与生产环境)

在实际开发中,开发环境和生产环境的配置有很多是相同的,通常我们把这些相同配置提取出来,以供开发环境和生产环境来使用。

我们可以通过配置NODE环境变量 通过判断来实现不同配置信息,webpack也提供了webpack-merage 可以帮助我们更简单方便的合并webpack配置文件。

shell 复制代码
    npm install webpack-merage -D

创建三个配置文件

  • webpack.development.js 开发环境配置
  • webpack.production.js 生产环境配置
  • webpack.common.js 公共配置 webpack-merage语法:
js 复制代码
   //webpack.common.js
   const path = require('path')
   module.exports = {
        ······
        //配置信息
   }
   
   
   //webpack.development.js
   const { merge } = require('webpack-merage')
   const common = require('./webpack.common.js')
   module.exports = merge(common,{
           ····开发环境的配置信息
   });
   
   //webpack.production.js 与开发环境配置文件类似

通过配置packages.json文件来使用不同的配置文件 例:

json 复制代码
    "script":{
        "start":"cross-env NODE_ENV=development webpack serve --config webpack.development.js"
        "build":"cross-env NODE_ENV=production webpack --config webpack.production.js"
    }

性能优化

webpack-bundle-analyzer

webpack-bundle-analyzer是一个非常有用的webpack可视化优化分析工具,他可以帮我们分析打包后的资源体积大小,并可以分析该资源由哪些模块组成。

shell 复制代码
    npm install webpack-bundle-analyzer -D
js 复制代码
    //webpack.config.js
    const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    ······
        plugins:{
            new BundleAnalyzerPlugin();
        }
    ······

speed-measure-webpack-plugin

webpack优化需要关注得除资源组成与大小外,还需要关注打包花费的时间。speed-measure-webpack-plugin可以帮我们分析打包过程中预处理器与插件等花费得时间。

js 复制代码
    const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
    const smp = new SpeedMeasurePlugin();
    let config = {
     //配置项
    }
    module.exports = smp.wrap(config)

资源压缩

对于JS文件压缩,可以使用插件terser-webpack-plugin,可以通过plugins插件形式,也可以通过opotimization配置 对于CSS文件压缩可以使用插件css-minimizer-webpack-plugin,通过opotimization配置。

例:

js 复制代码
    const TerserPlugin = require("terser-webpack-plugin");
    const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
    module.exoprts = {
        module:{
            rules:[{
                test:'/\.(scss|css)$/',
                use:[MiniCssExtractPlugin.loader,'css-loader','sass-loader']
            }]  
        },
        plugins:[
            new MiniCssExtractPlugin({
                filename:'[name]-[contenthash:8].css',
                chunkFilename:'[id].css',
            })
        ],
        optimization : {
            minimize:true,
            minimizer:[new TerserPlugin(),new CssMinimizerPlugin()],  //压缩器
        }
    }

缩小查找范围

exclude与include 设置处理范围

通过对预处理器设置exclude和include字段,设置处理范围。例如使用babel-loader,node_modules中的第三方包一般都进行过转码处理,所以可以将此目录排除在babel-loader处理范围。

module.noParse 排除解析模块

通过module.noParse,有些模块不需要被任何预处理器解析,例如jQuery,Lodash这一类的库。

resolve.modules 快速搜寻第三方包

用于配置webpack如何搜索第三方模块的路径。

resolve.extensions 匹配文件后缀名

用于webpack匹配文件后缀名。 import {name} from './b'; //省去了.js 通过配置 extensions : ['.js','.json']

splitChunks

用途:抽离公共代码。 参数:

  • chunks:表示什么类型的chunks里提取代码,有三个字符串值,分别为:'initial(只从入口chunks提取代码)'、'async(从动态加载的chunks提取)'、'all(all表示从上两者中都提取代码)'可以使用,还可以通过函数来匹配要提取的chunks。默认值为async。
  • miniSize:提取出来的chunk的最小体积,只有到达这个值才会被提取,默认20 000 (20Kb)
  • maxSize:表示提取出来的chunk的最大体积,其默认值是0,表示不限制最大体积。它是一个可违反的值,在被违反时起到提示作用。
  • minChunks:默认值是1,表示拆分前至少被多少个chunks引用的模块才会被提取。
  • maxAsyncRequests:按需(异步)加载时的最大并行请求数。
  • maxInitialRequests:入口点的最大并行请求数
  • cacheGroups:缓存组,可以继承或覆盖来自splitChunks.*的任何配置,几个重要参数
    • priority:缓存组优先级。一个模块可以有多个缓存组,其priorty的默认值是负数,自定义组priority的默认值是0。
    • reuseExistingChunk:是否重用chunk。若当前chunk中包含从主bundle中拆分出的模块,则它将被重用,而不是生成新的模块,其默认值为true。
    • test:匹配模块资源路径或chunk名称,其值可以是布尔值、正则表达式或字符串,若其值缺省则会选择所有模块。

优先级 minSize > maxSize > maxInitialRequests/maxAsyncRequests

使用TreeShaking

Tree Shaking可以检测模块中没有用到的代码块,在webpack打包时将它们移除从而减小打包后的资源体积。 开启Tree Shaking,对于webpack5 已经可以做到深层次Tree Shaking。

注:生产环境我们不会开启Tree Shaking 会影响构建速度,生产环境我们将mode改为production,即可自动打开Tree Shaking。

手动开启Tree Shaking

js 复制代码
    const TerserPlugin = require("terser-webpack-plugin");
    ······
    optimization:{
        usedExports:true,
        minimize:true,
        minimizer:[new TerserPlugin()],
    }

排除Tree Shaking文件 如polyfill

js 复制代码
    {
        "sideEffects":[
            "./polyfill.js"
        ]
    }

通过webpack构建Vue项目

项目结构:

  • src
  • -- main.ts
  • -- App.vue
  • webpack.config.js
  • index.html
  • package.json

基础构建

一、构建项目目录

生产package.json文件

shell 复制代码
    npm init -y 

新建webpack.config.js、index.html、src目录(下有mian.js、App.vue文件)。

二、安装相关依赖

安装webpack、webpack-cli(命令行)、webpack-dev-server(本地服务)、vue、vue-loader(解析vue文件)、html-webpack-plugin(使用html模板)。 也可以安装一些其他的插件 如:我们项目中需要使用sass,可以安装sass、sass-loader。 将css代码提取出来可以使用 mini-css-extract-plugin 。

shell 复制代码
    npm install webpack webpack-cli webpack-dev-server -D
    npm install vue 
    npm install vue-loader -D
    npm install sass sass-loader -D
    npm install html-webpack-plugin -D
    npm install mini-css-extract-plugin -D

三、配置webpack.config.js

注:参考示例,并不可直接使用。

js 复制代码
const path = require('path');

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

const { VueLoaderPlugin }= require('vue-loader');

module.exports = {
  entry: './src/main.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name]-[chunkhash].js',
    clean:true;//清空上次打包的结果
  },
  
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },
      {
       test:'/\.(scss|css)$/',
       use:['style-loader','css-loader','sass-loader']
       // use:[MiniCssExtractPlugin.loader,'css-loader','sass-loader'] 生产
      },  
    ]
  },
  plugins:[
    new HtmlWebpackPlugin({
      template: './index.html',
    }),
    new VueLoaderPlugin(),
  ],
   optimization: {
    splitChunks: {
      cacheGroups: {
        moment: {
          test: /[\\/]node_modules[\\/]/,
          priority:-10,
          chunks: "all",
          reuseExistingChunk:true,
        },
        common: {
          chunks: "all",
          priority:-20
          minChunks: 2,
          reuseExistingChunk:true,
        },
      },
    },
  },
  mode:'development',
}

可以通过npx webpack来打包 npx webpack serve 启动服务,也可以通过package.json文件配置脚本。

更多详细配置可以参考上文相关webpack基本配置介绍,比如说我们还可以通过插件压缩JS、CSS代码,压缩图片,通过splitChunks进行公共代码抽离。还可以通过安装ts和ts-loader来使用ts开发。

总结

本篇文章主要是对webpack基本配置的一些总结,其次通过webpack手动配置vue项目,可以帮助我们加深对webpack的了解,方便以后的灵活运用,对以后工作中的项目优化会提供一些帮助。
如果文章中有描述错误或不清晰的地方,希望可以帮忙指正。

相关推荐
还是大剑师兰特6 分钟前
面试题:ES6模块与CommonJS模块有什么异同?
前端·es6·大剑师
胡西风_foxww22 分钟前
【ES6复习笔记】数值扩展(16)
前端·笔记·es6·扩展·数值
mosen86824 分钟前
uniapp中uni.scss如何引入页面内或生效
前端·uni-app·scss
白云~️24 分钟前
uniappX 移动端单行/多行文字隐藏显示省略号
开发语言·前端·javascript
沙尘暴炒饭26 分钟前
uniapp 前端解决精度丢失的问题 (后端返回分布式id)
前端·uni-app
昙鱼40 分钟前
springboot创建web项目
java·前端·spring boot·后端·spring·maven
天天进步20151 小时前
Vue项目重构实践:如何构建可维护的企业级应用
前端·vue.js·重构
小华同学ai1 小时前
vue-office:Star 4.2k,款支持多种Office文件预览的Vue组件库,一站式Office文件预览方案,真心不错
前端·javascript·vue.js·开源·github·office
APP 肖提莫1 小时前
MyBatis-Plus分页拦截器,源码的重构(重构total总数的计算逻辑)
java·前端·算法
问道飞鱼1 小时前
【前端知识】强大的js动画组件anime.js
开发语言·前端·javascript·anime.js