问题
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 try to do it with typescript I run into some problems.
index.ts
export const someThing = something => import("./lazy/lazy");
and
lazy/lazy.ts
export default "I am lazy";
when I run it without any webpack configuration and name the files to ".js" I get a main chunk and a small chunk for the lazy loaded module.
But when I run it as ".ts" files with a simple webpack configuration I get just the "main.js" file and no extra chunk.
webpack.config.js
let config = {
resolve: {
extensions: [".ts", ".js"]
},
module: {
rules: [
{ test: /\.ts$/, use: ["ts-loader"], exclude: /node_modules/ },
]
},
}
module.exports = config;
and
tsconfig.json
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"noImplicitAny": false,
"sourceMap": true,
"lib": [ "es6", "dom" ],
"removeComments": true
}
}
Is there something to configure I am mission? What exactly is the difference between the import of a "js" file to a "ts" file?
回答1:
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 tomodule.exports.LoadMe = () => require('a-module')
, Webpack can't know if it's dynamic or just a normalrequire
"module": "esnext"
compiles toexport const LoadMe = () => import('a-module')
, Webpack knows it's dynamic because it's a call expression toimport
回答2:
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.
回答3:
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;
};
}
来源:https://stackoverflow.com/questions/49410022/webpack-lazy-loading-with-typescript