Webpack bundling module which I want to be loaded dynamically to entry point

Viewed 441

Below code seems like using the dynamic import:

(function executeApplication(): void {

  const loadDataButton: HTMLElement | null = document.getElementById("LoadDataButton");
  if (loadDataButton !== null) {
    loadDataButton.addEventListener("click", (): void => {
      (async function handler(): Promise<void> {
        console.log("Checkpoint 1");
        const loadedValue: string = await loadDataOnDemand();
        console.log(loadedValue);
      })().catch((): void => { /* */ });
    });
  }
})();


async function loadDataOnDemand(): Promise<string> {

  console.log("Checkpoint 2");
  const MODULE: { default: string; DYNAMICALLY_LOADED_CONST_FROM_TS_MODULE: string; } =
      await import("./DynamicLoadingTesting/TypeScriptModuleForDynamicLoading");
  console.log("Checkpoint 3");
  console.log(MODULE);


  return MODULE.DYNAMICALLY_LOADED_CONST_FROM_TS_MODULE;
}

However actually TypeScriptModuleForDynamicLoading.ts has been bundled to entry point:

FrontendLogicPreProcessingTesting:
  asset FrontendLogicPreProcessingTesting.js 11.2 KiB [emitted] (name: FrontendLogicPreProcessingTesting)
  ./FrontendLogicPreProcessingTesting.ts 2.28 KiB [built] [code generated]
  ./DynamicLoadingTesting/TypeScriptModuleForDynamicLoading.ts 419 bytes [built] [code generated]
  FrontendLogicPreProcessingTesting (webpack 5.4.0) compiled successfully in 710 ms

enter image description here

No webpack errros, and in output in browser seems to be correct:

enter image description here

My Webpack config:

{
  name: 'FrontendLogicPreProcessingTesting',
  context: 'D:\\IntelliJ IDEA\\XXXXX\\ProjectBuildingCommonTest\\00-Source\\FrontendLogicPreProcessingTesting'
,
  target: 'web',
  entry: {
    FrontendLogicPreProcessingTesting: 'D:/IntelliJ IDEA/XXXXX/ProjectBuildingCommonTest/00-Source/FrontendLogic
PreProcessingTesting/FrontendLogicPreProcessingTesting.ts'
  },
  output: {
    path: 'D:\\IntelliJ IDEA\\XXXXX\\ProjectBuildingCommonTest\\01-DevelopmentBuild\\FrontendLogicPreProcessin
gTesting',
    publicPath: './',
    filename: '[name].js',
    chunkFilename: 'loading_on_demand/partial__[id].js'
  },
  mode: 'development',
  watch: true,
  devtool: 'eval-cheap-source-map',
  module: {
    rules: [
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object], [Object],
      [Object]
    ]
  },
  resolve: {
    extensions: [ '.mjs', '.js', '.ts' ],
    alias: { vue: 'vue/dist/vue.common.js' }
  },
  plugins: [
    DefinePlugin { definitions: [Object] },
    ForkTsCheckerWebpackPlugin { options: [Object] },
  ],
  optimization: { minimize: false, emitOnErrors: true }
}

I using webpack 5.x.x., but I faced with same problem when used 4.x.x.

My TypeScript config:

{
  "compilerOptions": {

    "target": "es2017",
    "strict": true,

    "module": "CommonJS",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "allowJs": false,

    "experimentalDecorators": true,

    "baseUrl": "./",
    "paths": {

    },

    "noUnusedParameters": true,
    "noImplicitReturns": true
  }
}

Which conditions of dynamic loading has not been satisfied?

2 Answers

You are currently using module: "CommonJS" inside tsconfig.json, which will cause all dynamic import() to be transformed into require() calls before Webpack can actually see them. For Webpack to be able to generate new chunks, Webpack has to see dynamic import() calls.

Setting module: "esnext" will make it so the dynamic import() aren't transformed into require(), so Webpack can handle them properly.

webpackMode: lazy magic comment might help.

It should generate a separate chunk for DynamicLoadingTesting/TypeScriptModuleForDynamicLoading.js.

async function loadDataOnDemand(): Promise<string> {

  console.log("Checkpoint 2");
  const MODULE: { default: string; DYNAMICALLY_LOADED_CONST_FROM_TS_MODULE: string; } =
      await import(
       /* webpackMode: "lazy" */
       "./DynamicLoadingTesting/TypeScriptModuleForDynamicLoading"
);
  console.log("Checkpoint 3");
  console.log(MODULE);


  return MODULE.DYNAMICALLY_LOADED_CONST_FROM_TS_MODULE;
}
Related