【webpack】从vue-cli 2x 到 3x 迁移与实践

本文涉及的产品
全局流量管理 GTM,标准版 1个月
云解析 DNS,旗舰版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
简介: 【webpack】从vue-cli 2x 到 3x 迁移与实践

微信截图_20220511101600.png


1.为什么需要webpack


  • css预处理器如less、sass等浏览器不支持
  • 部分低版本浏览器不支持es6语法,需要转换为es5语法,为浏览器使用
  • 项目依赖过多,文件过多,需要将复杂的代码结构转换为细化
  • 模块化开发,保留单个模块的可维护性,又减少了http请求数,优化加载速度


2.什么是webpack


webpack是前端打包工具,通过分析所在项目的目录结构,找到模块及各模块间的依赖关系,且将浏览器不能直接运行的语言如typescript、css预处理器语法(less、sass)等或者因为浏览器因为版本底不支持新的内置函数,需要将其转换及打包成浏览器支持格式


  • 模块合并打包
  • 代码转换
  • 文件优化


接下来介绍下vue不同版本脚手架webpack使用配置的区别


3.webpack的使用


3.1 vue脚手架中的webpack目录结构


微信截图_20220511101615.png


左图项目结构为vue-cli 2x版本脚手架生成的项目,build文件夹包含了webpack配置


右图项目结构为vue-cli 3x版本脚手架生成的项目,3x版本并不存在该文件,而是将其配置集成到vue.config.js中


3.2 webpack配置(vue-cli 2x)


3.2.1 配置文件


webpack配置文件有三个


  • webpack.dev.conf.js   ( 开发环境运行的webpack配置文件 )
  • webpack.prod.conf.js   ( 生产环境运行的webpack配置文件 )
  • webpack.base.conf.js    ( webpack的基础配置文件,前两者都需要依赖它 )


针对不同环境的配置,运行不同的配置文件


(1)webpack.base.conf.js 结构


'use strict'
const path = require('path')
const utils = require('./utils')
const config = require('../config')
const vueLoaderConfig = require('./vue-loader.conf')
function resolve (dir) {
  return path.join(__dirname, '..', dir)
}
module.exports = {
  entry: {
    app: './src/main.js'
  },
  output: {
    path: config.build.assetsRoot,
    filename: '[name].js',
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        loader: 'vue-loader',
        options: vueLoaderConfig
      },
      {
        test: /\.js$/,
        loader: 'babel-loader',
        resolve('node_modules/webpack-dev-server/client')]
      },
      {
          test: /\.less$/,
            use: ['style-loader', 'css-loader', 'less-loader', {
                loader: 'postcss-loader',
                options: {
                    plugins: () => [
                        require('autoprefixer')({
                            overrideBrowserslist: ['last 2 versions', '>1%']
                        })
                    ]
                }
            }]
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: 'url-loader',
        options: {
          limit: 10000,
          name: utils.assetsPath('img/[name].[hash:7].[ext]')
        }
      },
    ]
  },
  plugins: [
        new HtmlWebpackPlugin({
            title: '首页',
            template: 'index.html',
            filename: 'index.html'
        }),
        new CleanWebpackPlugin(),
    ]
}


涉及到的配置知识


  • entry - 让 webpack 知道使用哪个模块,来作为构建其内部依赖图的开始
  • output - 让 webpack 知道在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist
  • loader - 处理浏览器不能直接运行的语言,可以将所有类型的文件转换为 webpack 能够处理的有效模块 ( 如上图 vue-loader用于解析和转换 .vue 文件,babel-loader 用于转换浏览器因不兼容es6写法的转换 常见loader还有TypeScript、Sass、Less、Stylus


babel-loader:解析 .js 和 .jsx 文件
tsx-loader:处理 ts 文件
less-loader:处理 less 文件,并将其编译为 css
sass-loader:处理 sass、scss 文件,并将其编译为 css
postcss-loader:// 解析CSS文件并且添加浏览器前缀到 CSS 内容里
module.exports = {
  plugins: [require('autoprefixer')],
};
css-loader:处理 css 文件
style-loader:将 css 注入到 DOM
file-loader:将文件上的import  /  require 解析为 url,并将该文件输出到输出目录中
url-loader:用于将文件转换成 base64 uri 的 webpack 加载程序
html-loader:将 HTML 导出为字符串, 当编译器要求时,将 HTML 最小化


  • plugins - 通过插件引入来处理,用于转换某种类型的模块,可以处理:打包、压缩、重新定义变量等


webpack官方文档链接 🔗


(2) webpack.dev.conf.js 结构


开发环境的webpack配置文件,依赖了base.conf,需要将其合并后再执行


'use strict'
// webpack.dev.js
const webpack = require('webpack')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const devWebpackConfig = merge(baseWebpackConfig, {
  devServer: {
    hot: true,
    contentBase: false, // since we use CopyWebpackPlugin.
    compress: true,
    host: '0.0.0.0',
    port: 8080,
    open: true,
  },
})


开发环境时,如上所示,需要配置devServer属性,通过webpack-dev-server 的这些选项改变,来改变其行为,常用配置有:


  • hot -  是否启用 webpack的模块热替换功能
  • host - 指定使用一个 host可以让外部访问。默认是 localhost
  • port - 指定要监听请求的端口号
  • compress - 是否启动gzip压缩
  • open - 告诉 dev-server 在 server 启动后是否打开浏览器


更多配置前往 🚀 官网dev-server配置


(3) webpack.prod.conf.js 结构


// webpack.prod.conf.js 
'use strict'
const path = require('path')
const utils = require('./utils')
const webpack = require('webpack')
const config = require('../config')
const merge = require('webpack-merge')
const baseWebpackConfig = require('./webpack.base.conf')
const CopyWebpackPlugin = require('copy-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const env = require('../config/prod.env');
const  Version = new Date().getTime();
const webpackConfig = merge(baseWebpackConfig, {
    output: {
        path: config.build.assetsRoot,
        filename: utils.assetsPath('js/[name].[chunkhash]'+ Version+'.js'),
        chunkFilename: utils.assetsPath('js/[id].[chunkhash]'+ Version+'.js')
    },
    plugins: [
        new UglifyJsPlugin(),
        new ExtractTextPlugin({
            filename: utils.assetsPath('css/[name].[contenthash]'+Version+'.css'),
            allChunks: true,
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'app',
            async: 'vendor-async',
            children: true,
            minChunks: 3
        }),
        new CopyWebpackPlugin([
            {
                from: path.resolve(__dirname, '../static'),
                to: config.build.assetsSubDirectory,
                ignore: ['.*']
            }
        ])
    ]
})
module.exports = webpackConfig


常用plugins插件的功能分解:


  • process.env


webpack编译过程中设置全局变量process.env


new webpack.DefinePlugin({
  'process.env': require('../config/dev.env.js')
}


或者通过命令行配置(用到cross-env)


cross-env NODE_ENV=production webpack --config webpack.config.prod.js


  • UglifyJsPlugin - 专门用来压缩js文件的
  • ExtractTextPlugin -  压缩提取出来的CSS
  • HtmlWebpackPlugin


new HtmlWebpackPlugin({
            title: '首页',
            template: 'index.html',
            filename: 'index.html'
        }),


生成 html 文件,并将包添加到 html 中


  • copy-webpack-plugin  - 拷贝文件


3.2.2 命令行工具


运行webpack命令行工具,前一章讲了webpack配置的用法,下面是CLI 用法,两者可替代


微信截图_20220511101631.png


webpack-dev-server  //启动开发服务器  
--open    //打开浏览器
--config webpack.dev.js //设置运行此脚本时执行的配置文件为webpack.dev.js
--progress //显示进度条


  • 开发环境: 运行 npm run dev,执行webpack.dev.conf.js 配置文件,通过webpack-dev-server来启动一个服务到端口(默认8080)访问localhost:8080,来为你的静态资源及bundle(自动编译)服务。通过访问http://localhost:8080/webpack-dev-server/bundle,bundle每次重编译后浏览器页面都会自动更新。


  • 生产环境: 运行 npm run build, 将执行编译打包各个模块,生成bundle.js(打包模块生成)等静态资源到目录(默认dist),再将js插入到html页面,以便访问浏览器时加载资源文件,触发立即执行函数


3.3 webpack配置(vue-cli 3x)


vue-cli3 创建的时候并不会自动创建vue.config.js,因为这个是个可选项,需要修改webpack的时候才会自己创建一个vue.config.js,把webpack的配置加入到vue.config.js


// vue.config.js
const path = require('path');
function resolve(dir) {
  return path.join(__dirname, '.', dir);
}
const productionGzipExtensions = /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i;
const CompressionWebpackPlugin = require('compression-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
  outputDir: 'dist',
  runtimeCompiler: false,
  productionSourceMap: false, 
  chainWebpack: (config) => {
    config.output.filename('[name].[hash].js').end();
    config.resolve.alias.set('@', path.resolve('src'));// 添加别名
    config.entry('main').add('babel-polyfill');
  },
  configureWebpack: () => {
    if (process.env.NODE_ENV === 'production') {
      return {
        plugins: [
          new CompressionWebpackPlugin({
            filename: '[path].gz[query]',
            test: productionGzipExtensions,
            threshold: 2048,
            minRatio: 0.8,
          }),
          new UglifyJsPlugin({
            uglifyOptions: {
              compress: {
                drop_debugger: true,
                drop_console: true,
              },
              sourceMap: false,
              parallel: true,
            },
          }),
        ],
      };
    }
    return false;
  },
  css: {
    extract: true,
    sourceMap: false,
    modules: false,
  },
  devServer: {
    port: 8088,
    host: '0.0.0.0',
    hotOnly: false,
  },
    pluginOptions: {
     // ...
    }
};


  • outputDir - 生产环境构建文件的目录,相当于webpack中的output
  • devServer - 就是相当于配置webpack-dev-server中的行为
  • css - extract配置(是否使用css分离插件 ExtractTextPlugin)
  • pluginOptions - 第三方插件配置
  • configureWebpack -  webpack 配置


通过process.env.NODE_ENV 去区分环境不同执行不同的命令


附上Vue-cli 3x 官方配置文档🚀



相关文章
|
6月前
|
前端开发
构建工具对比:Webpack与Rollup的前端工程化实践
在现代前端开发中,前端工程化变得愈发重要。本文将对两个常用的构建工具——Webpack和Rollup进行比较,探讨它们在前端工程化实践中的特点、优势和适用场景。无论是大型应用的打包优化还是轻量级库的构建,选择适合的构建工具都能提高开发效率和项目性能。
127 1
|
29天前
|
前端开发 JavaScript
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
手敲Webpack 5:React + TypeScript项目脚手架搭建实践
|
1月前
|
前端开发 JavaScript 开发者
构建工具对比:Webpack与Rollup的前端工程化实践
【10月更文挑战第11天】本文对比了前端构建工具Webpack和Rollup,探讨了它们在模块打包、资源配置、构建速度等方面的异同。通过具体示例,展示了两者的基本配置和使用方法,帮助开发者根据项目需求选择合适的工具。
26 3
|
4月前
|
缓存 JSON 前端开发
Webpack打包优化实践
【7月更文挑战第17天】Webpack的打包优化是一个持续的过程,需要开发者根据项目的实际情况选择合适的优化策略。通过拆分代码、压缩代码、使用Tree Shaking、优化加载器配置、利用缓存以及进行性能分析,我们可以有效提升Webpack的打包效率和应用的加载
|
6月前
|
缓存 资源调度 监控
Webpack 5新特性详解与性能优化实践
Webpack 5通过确定性的Chunk ID、模块ID和导出ID实现了长期缓存,这意味着相同的输入将始终产生相同的输出。这样,当你的用户再次访问更新后的网站时,浏览器可以重用旧的缓存,而不是重新下载所有资源。
87 2
|
6月前
|
前端开发 UED
探索前端工程化之路:Webpack、Rollup等构建工具对比与实践
在现代前端开发中,工程化成为不可或缺的一环。本文将深入探讨常用的前端构建工具Webpack和Rollup,并比较它们在实践中的优劣势。通过对功能、性能、插件生态等方面的评估,帮助读者选择适合自己项目需求的构建工具。
94 1
|
6月前
|
JSON JavaScript 前端开发
IDEA搭建vue-cli | vue-router | 排错思路、Webpack、Axios、周期、路由、异步、重定向
IDEA搭建vue-cli | vue-router | 排错思路、Webpack、Axios、周期、路由、异步、重定向
228 0
|
JavaScript 测试技术 Shell
[笔记]vue从入门到入坟《五》vue-cli构建vue webpack项目
[笔记]vue从入门到入坟《五》vue-cli构建vue webpack项目
|
缓存 前端开发 数据可视化
Webpack4 性能优化实践 #108
Webpack4 性能优化实践 #108
109 0
|
JavaScript 前端开发
第十七章 webpack5项目搭建Vue-Cli(开发模式)
本章介绍配置Vue-cli开发模式的步骤
262 0
第十七章 webpack5项目搭建Vue-Cli(开发模式)
下一篇
无影云桌面