2

我有延迟加载和 webpack 的问题。

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

index.ts

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

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

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

但是当我使用简单的 webpack 配置将它作为“.ts”文件运行时,我只得到“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”文件到底有什么区别?

4

3 回答 3

10

动态导入是一个 ES 特性,你需要告诉 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
于 2018-03-21T15:16:20.387 回答
1

无法将 Typescript 编译器配置为不触及某些导入。旧的延迟加载方式也同样有效:

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;
    };
}
于 2019-08-28T11:41:36.723 回答
0

我有一个技巧来延迟加载具有其类型的模块:

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

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

于 2018-08-21T06:39:05.787 回答