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
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;
};
}
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.
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