Webpack Lazy Loading with Typescript

后端 未结 3 1077
南笙
南笙 2021-01-23 00:19

I have a problem with lazy loading and webpack.

There is a video of Sean Larkin showing how easy it is with webpack 4 to create a lazy loaded bundle (Here). But when I t

相关标签:
3条回答
  • 2021-01-23 00:34

    There is no way to configure the Typescript compiler to not touch certain imports. The old way of lazy loading works just as well though:

    require.ensure([], require => {
      const lodash = require('lodash') as typeof import('lodash');
    }, 'lodash-chunk');
    

    this can be wrapped in a promise to achieve a very similar behavior to the ES6 import

    function importLodash(): Promise<typeof import('lodash')> {
        return new Promise((resolve, reject) => {
            require.ensure([], require => {
                resolve(require('lodash'))
            }, reject, 'lodash-chunk');
        })
    }
    
    // then use it
    
    const lodash = await importLodash();
    

    *note- require.ensure is not generic - this function will need to be duplicated for every module you want to lazy load.

    You'll also need to declare the require.ensure interface based on your enabled libs. I use this in my custom typings file

    /* typings.d.ts */
    
    declare global {
        const require: {
            // declare webpack's lazy loading interface
            ensure(deps: string[], cb: (lazyRequire: (path: string) => any) => void, chunkName: string): void;
            ensure(deps: string[], cb: (lazyRequire: (path: string) => any) => void, errCb: (err: Error) => void, chunkName: string): void;
        };
    }
    
    0 讨论(0)
  • 2021-01-23 00:36

    I have a trick one to lazyLoad a module with its type:

    function lazyLoad(){ return let lazyModule:typeof import('xxx') = require('xxx'); }

    limitation: the xxx can only be string not a variable.

    0 讨论(0)
  • 2021-01-23 00:37

    Dynamic imports are an ES feature, you need to tell TypeScript to transform to ESNext to get import on the output, just change "module": "commonjs" to "module": "esnext".

    Take this code :

    export const LoadMe = () => import('./a-module')
    
    • "module": "commonjs" compiles to module.exports.LoadMe = () => require('a-module'), Webpack can't know if it's dynamic or just a normal require
    • "module": "esnext" compiles to export const LoadMe = () => import('a-module'), Webpack knows it's dynamic because it's a call expression to import
    0 讨论(0)
提交回复
热议问题