You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Vue CLI5项目中import与require导入JSON对Webpack构建时间的影响及相关问题咨询

Vue CLI5项目中import与require导入JSON对Webpack构建时间的影响及相关问题咨询

我仔细看了你的项目场景和代码,确实这个构建时间差异的核心原因在于Webpack对importrequire的处理逻辑不同,下面给你逐一拆解并解答你的疑问:


1. importrequire 在Webpack构建中的本质区别

结合你的代码场景来看,两者在Webpack编译流程里的处理方式天差地别:

  • 静态import(你的原始方案)
    你原locales/index.ts里的import en from "./en.json"; import id from "./id.json";属于静态导入,Webpack在编译初期的依赖分析阶段就会强制把这两个JSON文件全部解析、打包到产物中——不管你运行时实际用不用其中一个。
    加上你项目里有上百个页面都在调用i18n的t函数,Webpack需要处理所有页面与这两个大JSON文件的依赖关联,做大量的模块依赖图分析;而且Vue I18n的消息文件是完整的对象,几乎无法通过tree-shaking剔除未使用的语言文案,这直接导致编译工作量暴增。

    你的原始locales/index.ts代码:

    import { createI18n } from "vue-i18n";
    import en from "./en.json";
    import id from "./id.json";
    
    const i18n = createI18n({
        legacy: false,
        locale: process.env.VUE_APP_LANG,
        messages: {
            en,
            id,
        },
    });
    
    export default i18n;
    
  • 带构建时变量的require(你的优化方案)
    你修改后的require(./${langJsonMap[lang]}.json)中,lang来自process.env.VUE_APP_LANG——这个变量在Vue CLI构建时是静态确定的常量(通过.env文件或构建命令传入)。
    Webpack会在编译阶段直接替换这个变量的值,只加载对应语言的JSON文件,完全忽略另一个语言的文件。这样一来,Webpack需要处理的依赖体积直接减半,还省去了处理未使用文件的所有依赖关联,编译步骤自然大幅简化。

    你的优化后locales/index.ts代码:

    import { createI18n } from "vue-i18n";
    
    type LangMessages = Record<string, string>;
    const lang = process.env.VUE_APP_LANG;
    const langJsonMap: Record<string, string> = {
        en: "en",
        id: "id",
    };
    
    const json = require(`./${langJsonMap[lang]}.json`) as LangMessages;
    const i18n = createI18n({
        legacy: false,
        locale: process.env.VUE_APP_LANG,
        messages: {
            [process.env.VUE_APP_LANG]: json,
        },
    });
    
    export default i18n;
    

2. 为什么构建时间差这么大?

你的原始方案中,Webpack需要完成这些高耗时操作:

  1. 解析并打包两个完整的大体积语言JSON文件(毕竟支撑上百个页面的文案,文件大小肯定不小)
  2. 为上百个页面与这两个JSON文件建立依赖关联,构建庞大的模块依赖图
  3. 尝试对i18n相关代码做tree-shaking,但由于你项目中i18n.global.tuseI18n的使用方式,Webpack无法剔除未使用的语言文案,只能全量打包

而优化后的方案中,Webpack只需要处理当前环境指定的单个JSON文件,依赖体积直接减少50%以上,还省去了大量的依赖关联分析工作,所以构建时间从180s骤降到40s是完全合理的。


3. 如何追踪构建时间消耗、直观对比差异?

针对Vue CLI项目,你可以用这几种方法精准定位耗时环节:

方法1:Vue CLI内置的构建分析报告

运行以下命令构建项目:

npm run build -- --report

构建完成后会在dist目录生成report.html,打开后可以直观看到:

  • 每个模块的体积大小
  • 模块之间的依赖关系
  • 哪些模块占用了最多的构建时间
    你可以分别用两种方案生成报告,对比后就能清晰看到未使用的JSON文件是否被打包,以及模块依赖分析的差异。

方法2:用speed-measure-webpack-plugin测量精准耗时

这个插件可以逐一定位Webpack每个loader和plugin的执行时间:

  1. 安装插件:
npm install speed-measure-webpack-plugin --save-dev
  1. vue.config.js中配置:
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeasurePlugin();

module.exports = smp.wrap({
  // 你的原有Vue CLI配置,比如lintOnSave、configureWebpack等
});
  1. 运行npm run build,控制台会输出每个环节的耗时数据,对比两种方案的输出就能明确看到处理JSON文件的耗时差异。

方法3:查看Webpack详细构建日志

运行:

npm run build -- --verbose

Webpack会输出包含每个模块编译时间、依赖解析时间的详细日志,你可以通过搜索en.jsonid.json相关的日志,对比两种方案中处理这些文件的时间差。


4. 后续优化建议

既然你的优化方案已经大幅提升了构建速度,建议继续沿用,同时注意:

  • 确保process.env.VUE_APP_LANG在构建时正确设置(比如通过.env.en.env.id文件,或者构建命令npm run build -- --env VUE_APP_LANG=en
  • 项目中已有的import i18n from "@/locales";useI18n的代码无需修改,因为优化后的i18n实例已经只包含当前语言的消息
  • 如果未来需要支持运行时多语言切换,可以改成动态import()的方式,但此时Webpack需要打包所有语言文件,构建时间会回升,你可以用Webpack的splitChunks把语言文件单独打包成异步chunk,优化用户的加载体验

备注:内容来源于stack exchange,提问作者greenbird

火山引擎 最新活动