如何使用rollupjs动态导入由参数定义名称的模块?

Pei*_* Li 4 rollup dynamic-import webpack rollupjs

src/dynamicImport.js

\n\n
\nexport default function dynamicImport(path) {\n    const parts = path.split(\'/\');\n    // \xe5\x8e\xbb\xe6\x8e\x89\xe5\x90\x8e\xe7\xbc\x80.js\n    const namespace = parts.pop().replace(/\\.\\w+$/, \'\');\n    let mid = \'\';\n\n    if (parts.length) {\n        mid = `${parts.join(\'/\')}/`;\n    }\n\n    return new Promise((resolve, reject) => {\n        console.log(mid, namespace)\n        import(\n            `@src/${mid}` + namespace + \'.js\'\n        )\n            .then(module => {\n                resolve(module);\n            })\n            .catch(err => {\n                reject(err);\n            });\n    });\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

src/index.js

\n\n
dynamicImport(\'lib/test\').then(({ default: test}) => {\n    test();\n})\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

src/lib/test.js

\n\n
export default function test() {}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

rollup.config.js

\n\n
const rollup = require(\'rollup\');\nconst babel = require(\'rollup-plugin-babel\')\nconst resolve = require(\'rollup-plugin-node-resolve\')\nconst commonjs = require(\'rollup-plugin-commonjs\')\nconst alias = require(\'@rollup/plugin-alias\')\nconst { uglify } = require(\'rollup-plugin-uglify\')\nconst postcss = require(\'rollup-plugin-postcss\')\nconst replace = require(\'@rollup/plugin-replace\')\nconst path = require(\'path\');\nconst getBabelConfig = require(\'./getBabelCommonConfig.js\');\n\nconst dirs = {\n    src: path.resolve(__dirname, \'../src\'),\n    dist: path.resolve(__dirname, \'../dist\'),\n}\n\n\n\nconst getInputOptions = (isDev, isMinify) => {\n    const babelConfig = getBabelConfig(false);\n    babelConfig.runtimeHelpers = true;\n    const inputOptions = {\n        input: path.resolve(dirs.src, \'index.js\'),\n        plugins: [\n            replace({\n                \'process.env.NODE_ENV\': isDev ? \'development\' : \'production\'\n            }),\n            postcss({\n                extensions: [\'.css\', \'.less\'],\n                extract: true,\n                modules: true,\n                minimize: isMinify\n            }),\n            alias({\n                resolve: ["",".js"],\n                entries: {\n                    \'@lib\': path.resolve(__dirname, \'../src/lib\'),\n                    \'@src\': path.resolve(__dirname, \'../src\')\n                }\n            }),\n            resolve({\n                extensions: ["",".js"],\n            }),\n            commonjs({\n                include: /node_modules/\n            }),\n            babel({\n                ...babelConfig,\n                extensions: [".js"]\n            })\n        ]\n    };\n\n    if (isMinify) {\n        inputOptions.plugins.push(uglify());\n    }\n\n    return inputOptions;\n}\n\nconst getOutputOptions = (isMinify) => {\n    return {\n        format: \'umd\',\n        file: path.resolve(dirs.dist, isMinify ? \'index.min.js\' : \'index.js\'),\n        name: \'test1\',\n        sourcemap: true\n    }\n}\n\nconst compile = async () => {\n    const inputOptions = getInputOptions(true, false);\n    const bundle = await rollup.rollup(inputOptions);\n    const outputOptions = getOutputOptions(false);\n    await bundle.generate(outputOptions);\n    await bundle.write(outputOptions);\n}\n\n\nconst build = async () => {\n    const inputOptions = getInputOptions(true, true);\n    const bundle = await rollup.rollup(inputOptions);\n    const outputOptions = getOutputOptions(true);\n    await bundle.generate(outputOptions);\n    await bundle.write(outputOptions);\n\n}\n\n\nconst watch = () => {\n    const watchOptions = {\n        ...getInputOptions(true),\n        output: [getOutputOptions()],\n        watch: {\n            exclude: \'node_modules/**\'\n        }\n    };\n\n    const watcher = rollup.watch(watchOptions);\n\n    watcher.on(\'event\', event => {\n        // event.code can be one of:\n        //   START        \xe2\x80\x94 the watcher is (re)starting\n        //   BUNDLE_START \xe2\x80\x94 building an individual bundle\n        //   BUNDLE_END   \xe2\x80\x94 finished building a bundle\n        //   END          \xe2\x80\x94 finished building all bundles\n        //   ERROR        \xe2\x80\x94 encountered an error while bundling\n        //   FATAL        \xe2\x80\x94 encountered an unrecoverable error\n    });\n}\n\nconst isDevelopment = [\'NODE_DEV\', \'BROWSER_DEV\'].indexOf(process.env.NODE_ENV) >= 0;\n\nif (isDevelopment) {\n    watch(true);\n} else {\n    compile();\n    build();\n}\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

这不是在 dist 中创建的 chunk js。仅构建了index.js。使用 rollup.js 构建代码时这不会出现错误。

\n\n

/dist/index.js

\n\n
(function (factory) {\n    typeof define === \'function\' && define.amd ? define(factory) :\n    factory();\n}((function () { \'use strict\';\n\n    function dynamicImport(path) {\n      var parts = path.split(\'/\'); // \xe5\x8e\xbb\xe6\x8e\x89\xe5\x90\x8e\xe7\xbc\x80.js\n\n      var namespace = parts.pop().replace(/\\.\\w+$/, \'\');\n      var mid = \'\';\n\n      if (parts.length) {\n        mid = "".concat(parts.join(\'/\'), "/");\n      }\n\n      return new Promise(function (resolve, reject) {\n        console.log(mid, namespace);\n        import("@src/".concat(mid) + namespace + \'.js\').then(function (module) {\n          resolve(module);\n        }).catch(function (err) {\n          reject(err);\n        });\n      });\n    }\n\n    dynamicImport(\'lib/test\').then(function (_ref) {\n      var test = _ref.default;\n      test();\n    });\n\n})));\n//# sourceMappingURL=index.js.map\n\n
Run Code Online (Sandbox Code Playgroud)\n\n

=============================================

\n\n

在 webpack 中我可以像这样动态导入模块:

\n\n
import(\n    /* webpackChunkName: "[request]" */\n    `@src/${mid}` + namespace\n ).then()\n
Run Code Online (Sandbox Code Playgroud)\n\n

我怎样才能用汇总来做到这一点。我需要使用参数传递模块名称。

\n

nic*_*ock 7

不幸的是,我发现汇总目前不支持动态导入中的变量。
请参阅这些问题:
https://github.com/rollup/rollup/issues/2463
https://github.com/rollup/rollup/issues/2097
它只能使用定义的字符串来完成:

function localeDynamicImport (locale) {
  if (lang === 'en') {
    return import('./locales/en.js');
  }

  if (lang === 'zh') {
    return import('./locales/zh.js');
  }
}
Run Code Online (Sandbox Code Playgroud)