【问题标题】:Module.exports with es6 import for webpack.config.ts in typescript带有 es6 导入的 Module.exports 用于 typescript 中的 webpack.config.ts
【发布时间】:2019-10-20 07:47:23
【问题描述】:

我正在使用带有 typescript 的 webpack,其配置在 typescript 中。指令here

在我的根目录下我有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;

然后我有两个项目,每个项目都有自己的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;

这一切都很好。 Here's这个工厂getConfig = () => {}风格的完整示例。

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

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

到 es6 导入。这甚至是 VS 代码作为建议提供的。

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

这是我的tsconfig.json 我已经启用了[allowSyntheticDefaultImports][5]。建议here

{
  "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"
  ]
}

但我还是添加了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

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

import getConfig from "../../webpack.config.base";
import * as base from "../../webpack.config.base";

删除webpack.config.base.ts中的export default getConfig;,将const getConfig直接导出为export const getConfig。但那时module.exports = getConfig 的意义何在。更不用说它也没有血腥的工作(和以前一样的问题)

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

我在这里缺少什么?为什么我不能简单地将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",

【问题讨论】:

    标签: typescript webpack import


    【解决方案1】:

    什么有效?

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

    • Node.js(版本11.12.0
    • TypeScript(版本3.5.3
    • webpack(版本4.39.1

    目录结构

    假设如下目录结构:

    project/
    ├── ...
    ├── webpack.common.ts
    ├── webpack.development.ts
    └── webpack.production.ts
    

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

    TypeScript 配置

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

    import webpack from 'webpack';
    
    const configuration: webpack.Configuration = {
      // Your common webpack configuration...
    };
    
    export default configuration;
    

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

    import webpack from 'webpack';
    import merge from 'webpack-merge';
    import commonWebpackConfiguration from './webpack.common';
    
    const configuration: webpack.Configuration = merge(commonWebpackConfiguration, {
      mode: 'development'
      // Your `development`-specific configuration...
    });
    
    export default configuration;
    

    同时,production 环境的 webpack 配置在 import/export 语法方面与用于development 环境的配置没有什么不同。

    进口和出口

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

    export default configuration;
    

    import commonWebpackConfiguration from './webpack.common';
    

    因此,没有用于导入和导出的 CommonJS 语法(例如 module.exportsrequire),这可以保持 webpack 配置文件的清洁并允许无缝工作流。根据webpack's documentation,这实际上是使用 webpack 和 TypeScript 的推荐方式。


    为什么您的配置不起作用

    第一次尝试

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

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

    到 es6 导入。这甚至是 VS 代码作为建议提供的。

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

    const helloWorld = () => {
      console.log('Hello, world!');
    };
    const bar = 'foo';
    
    export default helloWorld;
    export { bar };
    

    到 JavaScript 使用 tsc:

    "use strict";
    exports.__esModule = true;
    var helloWorld = function () {
        console.log('Hello, world!');
    };
    var bar = 'foo';
    exports.bar = bar;
    exports["default"] = helloWorld;
    

    第二次尝试

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

    在这种情况下,将allowSyntheticDefaultImports(你已经拥有)和esModuleInterop(你错过)添加到你的TypeScript配置tsconfig.json都设置为true可以解决这个问题1.

    第三次尝试

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

    import getConfig from "../../webpack.config.base";
    

    import * as base from "../../webpack.config.base";
    

    删除webpack.config.base.ts中的export default getConfig;,将const getConfig直接导出为export const getConfig。但到那时,module.exports = getConfig 的意义何在。

    拥有

    export const getConfig = () => {...};
    

    module.exports = getConfig;
    

    同时,会给你base === getConfig(因为只有module.exports = getConfig;生效)。因此,调用base.getConfig 会得到undefined,因为您定义的函数getConfig 没有属性getConfig。因此,“base.getConfig 不是函数”。

    导入语法互操作性

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

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

    是一个 CommonJS 导入,而

    import getConfig from "../../webpack.config.base";
    

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

    【讨论】:

      猜你喜欢
      • 2016-03-20
      • 1970-01-01
      • 2021-12-07
      • 2019-07-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多