使用Typescript加载Webpack延迟

时间:2018-03-21 15:12:24

标签: typescript webpack webpack-4

我在延迟加载和webpack时遇到问题。

有一个Sean Larkin的视频显示了webpack 4创建一个延迟加载的包(Here)是多么容易。但是当我尝试使用打字稿时,我遇到了一些问题。

index.ts

export const someThing = something => import("./lazy/lazy");

lazy/lazy.ts
export default "I am lazy";

当我在没有任何webpack配置的情况下运行它并将文件命名为" .js"我得到了一个主要的块和一个用于延迟加载模块的小块。

但当我把它作为" .ts"使用简单的webpack配置的文件我只得到" main.js"文件,没有额外的块。

webpack.config.js
let config = {
    resolve: {
        extensions: [".ts", ".js"]
    },
    module: {
        rules: [
            { test: /\.ts$/, use: ["ts-loader"], exclude: /node_modules/ },
        ]
    },
}

module.exports = config;

tsconfig.json
{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es5",
        "noImplicitAny": false,
        "sourceMap": true,
        "lib": [ "es6", "dom" ],
        "removeComments": true
    }
}

有什么东西要配置我是使命吗? 输入" js"之间的区别到底是什么?提交给" ts"文件?

3 个答案:

答案 0 :(得分:3)

Dynamic imports are an ES feature,您需要告诉TypeScript转换为ESNext以在输出上获取import,只需将"module": "commonjs"更改为"module": "esnext"

拿这段代码:

export const LoadMe = () => import('./a-module')
  • "module": "commonjs"汇编到module.exports.LoadMe = () => require('a-module'),Webpack无法知道它是动态还是只是正常require
  • "module": "esnext"编译为export const LoadMe = () => import('a-module'),Webpack知道它是动态的,因为它是import的调用表达式

答案 1 :(得分:0)

我有个窍门,可以懒加载其类型的模块:

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

限制: xxx只能是字符串而不是变量

答案 2 :(得分:0)

无法将Typescript编译器配置为不接触某些导入。 延迟加载的old way同样有效:

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

这可以包含在实现与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不是通用的-对于要延迟加载的每个模块,都需要复制此功能。

您还需要根据启用的库声明require.ensure接口。我在自定义类型文件中使用它

/* 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;
    };
}