Module.exports 与 es6 import for webpack.config.ts in typescript

Sig*_*gex 3 import typescript webpack

我将 webpack 与 typescript 一起使用,并在 typescript 中自行配置。说明在这里

在我的根里我有webpack.config.base.ts


import webpack from "webpack";

const getConfig = ( appDir: string, distDir: string, env: any, args: any ): webpack.Configuration => {
    const config: webpack.Configuration = {
        entry: {

        },
        output: {

        },
        resolve: {
            plugins: [

            ],
            extensions: [".ts", ".tsx", ".js"]
        },
        devtool: "source-map",
        module: {
            rules: [
            ]
        },
        plugins: [
        ]
    };

    return config;
};

module.exports = getConfig;
Run Code Online (Sandbox Code Playgroud)

然后我有两个项目,每个项目都有自己的webpack.config.ts

import webpack from "webpack";
import * as path from 'path';

const getConfig = require("../../webpack.config.base");

const appDir = __dirname;
const distDir  = path.resolve(__dirname, "../AppOne.Web/wwwroot");

const getConfigFactory = (env: any, args: any): webpack.Configuration => getConfig(appDir, distDir, env, args);

module.exports = getConfigFactory;
Run Code Online (Sandbox Code Playgroud)

这一切都工作得很好。这是这种工厂风格的完整示例getConfig = () => {}

我的问题是当我试图改变时

const getConfig = require("../../webpack.config.base");
Run Code Online (Sandbox Code Playgroud)

到 es6 导入。这甚至是 VS code 提供的建议。

在此输入图像描述

当我应用此更改时,我得到

在此输入图像描述

这是tsconfig.json我已经启用的[allowSyntheticDefaultImports][5]这里推荐。

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "moduleResolution": "node",
    "jsx": "react",
    "experimentalDecorators": true,
    "lib": [
      "es2015",
      "dom"
    ],
    "target": "es5",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "typeRoots": [
      "./node_modules/@types/",
      "./types/"
    ],
    "baseUrl": ".",
    "paths": { }
  },
  "include": [
    "./src/**/*.ts",
    "./src/**/*.tsx"
  ]
}
Run Code Online (Sandbox Code Playgroud)

但我export default getConfig;还是加了……又加npm run build了一次。它仍然失败。

const getConfigFactory = (env: any, args: any): webpack.Configuration => getConfig(appDir, distDir, env, args);
                                                                                  ^
TypeError: webpack_config_base_1.default is not a function
Run Code Online (Sandbox Code Playgroud)

在把头撞到桌子上之前我最后的尝试是改变

{
  "compilerOptions": {
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "moduleResolution": "node",
    "jsx": "react",
    "experimentalDecorators": true,
    "lib": [
      "es2015",
      "dom"
    ],
    "target": "es5",
    "forceConsistentCasingInFileNames": true,
    "noImplicitReturns": true,
    "noImplicitThis": true,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "noUnusedLocals": true,
    "typeRoots": [
      "./node_modules/@types/",
      "./types/"
    ],
    "baseUrl": ".",
    "paths": { }
  },
  "include": [
    "./src/**/*.ts",
    "./src/**/*.tsx"
  ]
}
Run Code Online (Sandbox Code Playgroud)
const getConfigFactory = (env: any, args: any): webpack.Configuration => getConfig(appDir, distDir, env, args);
                                                                                  ^
TypeError: webpack_config_base_1.default is not a function
Run Code Online (Sandbox Code Playgroud)

删除export default getConfig;其中的并直接webpack.config.base.ts导出为. 但到那时,还有什么意义呢。更不用说它也不起作用(与以前相同的问题)const getConfigexport const getConfigmodule.exports = getConfig

const getConfigFactory = (env: any, args: any): webpack.Configuration => base.getConfig(appDir, distDir, env, args);
                                                                              ^
TypeError: base.getConfig is not a function
Run Code Online (Sandbox Code Playgroud)

我在这里缺少什么?为什么我不能简单地替换const getConfig = require("../../webpack.config.base");import getConfig from "../../webpack.config.base"

附言。

这是我"scripts"运行这个的

    "build:appone": "webpack --mode=development --config ./src/AppOne.App/webpack.config.ts",
    "build:apptwo": "webpack --mode=development --config ./src/AppTwo.App/webpack.config.ts",
Run Code Online (Sandbox Code Playgroud)

Dan*_*rst 7

有什么作用?

\n\n

我使用TypeScript配置了webpack ,用于具有通用基本配置的多个环境(例如和)。为此,我利用:developmentproduction

\n\n
    \n
  • Node.js(版本11.12.0
  • \n
  • 打字稿(版本3.5.3
  • \n
  • 网页包(版本4.39.1
  • \n
\n\n

目录结构

\n\n

假设目录结构如下:

\n\n
project/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ...\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.common.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.development.ts\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 webpack.production.ts\n
Run Code Online (Sandbox Code Playgroud)\n\n

其他目录结构(例如示例中的两个嵌套项目)也将起作用。不过,您可能必须调整以下示例中使用的路径。

\n\n

TypeScript 配置

\n\n

webpack 的基本配置webpack.common.ts如下所示:

\n\n
project/\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 ...\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.common.ts\n\xe2\x94\x9c\xe2\x94\x80\xe2\x94\x80 webpack.development.ts\n\xe2\x94\x94\xe2\x94\x80\xe2\x94\x80 webpack.production.ts\n
Run Code Online (Sandbox Code Playgroud)\n\n

针对不同环境的两个 webpack 配置使用npm 包webpack-merge扩展了这个基本配置。您可以在npm 包@types/webpack-merge中找到 TypeScript 的类型。继续使用最初的示例,development环境的 webpack 配置如下所示:

\n\n
import webpack from \'webpack\';\n\nconst configuration: webpack.Configuration = {\n  // Your common webpack configuration...\n};\n\nexport default configuration;\n
Run Code Online (Sandbox Code Playgroud)\n\n

同时,环境的 webpack 配置与环境中使用的/语法production没有什么不同。developmentimportexport

\n\n

进出口

\n\n

您可能已经注意到,我使用ES6 import /export语法:

\n\n
import webpack from \'webpack\';\nimport merge from \'webpack-merge\';\nimport commonWebpackConfiguration from \'./webpack.common\';\n\nconst configuration: webpack.Configuration = merge(commonWebpackConfiguration, {\n  mode: \'development\'\n  // Your `development`-specific configuration...\n});\n\nexport default configuration;\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n
export default configuration;\n
Run Code Online (Sandbox Code Playgroud)\n\n

因此,不涉及用于导入和导出(例如或)的CommonJS语法,这可以保持 webpack 配置文件干净并允许无缝工作流程。这实际上是根据webpack 文档推荐的使用 webpack 和 TypeScript 的方法。module.exportsrequire

\n\n
\n\n

为什么你的配置不起作用

\n\n

第一次尝试

\n\n
\n

我的问题是当我尝试改变时

\n\n
const getConfig = require("../../webpack.config.base");\n
Run Code Online (Sandbox Code Playgroud)\n\n

到 es6 导入。这甚至是 VS code 提供的建议。

\n
\n\n

module.exports正如您观察到的错误所述,确实没有默认导出(即该对象module.exports没有任何名为 的属性)。\n使用ES6默认导出(即)实际上会创建一个名为的导出,就像其他命名导出一样(例如在下面)。这可以通过编译以下 TypeScript 片段来说明:default
export default defaultbar

\n\n
import commonWebpackConfiguration from \'./webpack.common\';\n
Run Code Online (Sandbox Code Playgroud)\n\n

JavaScript 使用tsc

\n\n
const getConfig = require("../../webpack.config.base");\n
Run Code Online (Sandbox Code Playgroud)\n\n

第二次尝试

\n\n
\n

但我export default getConfig;还是加了……又加npm run build了一次。它仍然失败。

\n
\n\n

在这种情况下,将allowSyntheticDefaultImports(您已经拥有的)和esModuleInterop(您错过的)添加到您的 TypeScript 配置中,tsconfig.json并将两者设置为1true可以解决该问题。

\n\n

第三次尝试

\n\n
\n

在把头撞到桌子上之前我最后的尝试是改变

\n\n
import getConfig from "../../webpack.config.base";\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n
import * as base from "../../webpack.config.base";\n
Run Code Online (Sandbox Code Playgroud)\n\n

删除export default getConfig;其中的并直接webpack.config.base.ts导出为. 但到那时,还有什么意义呢。const getConfigexport const getConfigmodule.exports = getConfig

\n
\n\n

拥有

\n\n
const helloWorld = () => {\n  console.log(\'Hello, world!\');\n};\nconst bar = \'foo\';\n\nexport default helloWorld;\nexport { bar };\n
Run Code Online (Sandbox Code Playgroud)\n\n

\n\n
"use strict";\nexports.__esModule = true;\nvar helloWorld = function () {\n    console.log(\'Hello, world!\');\n};\nvar bar = \'foo\';\nexports.bar = bar;\nexports["default"] = helloWorld;\n
Run Code Online (Sandbox Code Playgroud)\n\n

同时,会给你base === getConfig(一样才module.exports = getConfig;生效)。因此,由于您定义的函数没有 property ,因此调用base.getConfig会给出。因此,“不是一个函数”。undefinedgetConfiggetConfigbase.getConfig

\n\n

导入语法互操作性

\n\n
\n

为什么我不能简单地替换const getConfig = require("../../webpack.config.base");import getConfig from "../../webpack.config.base"

\n
\n\n
import getConfig from "../../webpack.config.base";\n
Run Code Online (Sandbox Code Playgroud)\n\n

CommonJS导入,而

\n\n
import * as base from "../../webpack.config.base";\n
Run Code Online (Sandbox Code Playgroud)\n\n

ES6导入。它们不能互换使用,因为它们本质上是不同的。您应该选择与其中之一合作,但不能同时与两者合作。

\n