条件静态要求导出的 ES6 导出等效项?

问题描述 投票:0回答:1

我在许多项目(如 React)中看到,他们使用

require()
有条件地重新导出属性,如下所示:

// index.js

if (process.env.NODE_ENV === 'production' {
  exports = require('./cjs/react.production.min.js')
} else {
  exports = require('./cjs/react.development.js')
}

我正在尝试将其转换为等效的有效 ES6 语法,保留单个导出的成员(用于树摇动)。

我已经尝试过了,它有效,但你无法导入个人成员:

import * as prod from './cjs/react.production.min.js'
import * as dev from './cjs/react.development.js'

let exports = {}

if (process.env.NODE_ENV === 'production') {
  exports = prod
} else {
  exports = dev
}

export default exports

是否有与使用有效 ES6 语法的原始版本等效的内容?

我想有了足够智能的编译器,嵌套模块中分配的键可以在构建时传播到顶层,如下所示:

import { value_1 as prod_value_1 } from './cjs/react.production.min.js'
import { value_1 as dev_value_1 } from './cjs/react.development.js'

let value_1 = undefined

if (process.env.NODE_ENV === 'production') {
  value_1 = prod_value_1
} else {
  value_1 = dev_value_1
}

export { value_1 /* value_2, etc */ }
javascript
1个回答
0
投票

将 CommonJS 中的条件

require()
语句转换为 ES6 语法,同时保留树摇动功能可能有点具有挑战性。您所描述的方法是正确的。但是,重要的是要了解 ES6
import
export
语句是静态的,不能在像
if
语句那样的条件块内使用。

您在问题后半部分描述的方法(导入单个成员然后有条件地分配它们)是处理此问题的一种方法。这是您的方法的扩展和稍微改进的版本:

import * as prod from './cjs/react.production.min.js';
import * as dev from './cjs/react.development.js';

let finalExports = {};

const keys = Object.keys(prod);
keys.forEach(key => {
  finalExports[key] = process.env.NODE_ENV === 'production' ? prod[key] : dev[key];
});

// Explicitly export each member
export const {
  Component1,
  Component2,
  // ... other exports
} = finalExports;

这种方法确实有一些缺点:

  1. 导出的显式列表:您需要手动列出所有 出口。这可能很麻烦并且容易出错,特别是如果 出口数量较多或变化频繁
  2. 构建时优化:虽然这种方法可能在运行时起作用,但它 对于构建时优化来说可能不如树那么有效 摇晃。由于实际使用的导出是在运行时确定的, 静态分析工具可能无法确定哪些导出 实际上在消费代码中使用。
  3. 捆绑包大小:生产版和开发版都导入并包含在 捆绑,这可能会导致捆绑尺寸更大。

另一种方法是使用 Webpack 或 Rollup 等构建工具来处理特定于环境的捆绑。这些工具可以在构建过程中根据环境替换导入,从而实现更高效的树摇动和更小的包大小。这是一个使用 Webpack 的示例

DefinePlugin
:

// webpack.config.js

const webpack = require('webpack');

module.exports = {
  // ... other webpack config
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
    })
  ],
  resolve: {
    alias: {
      'react': process.env.NODE_ENV === 'production' 
               ? './cjs/react.production.min.js' 
               : './cjs/react.development.js'
    }
  }
};

在源代码中,您只需从“react”导入,Webpack 将根据环境将其替换为正确的文件。这种方法更易于维护并且更适合优化。

© www.soinside.com 2019 - 2024. All rights reserved.