allowSyntheticDefaultImports

allowSyntheticDefaultImports

本文介绍了在TypeScript中使用webpack.config.ts的es6 import进行Module.exports的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将webpack与typescript一起使用,并且将其自身配置为typescript.说明此处

I'm using webpack with typescript with the config its self in typescript. Instructions here

在我的根目录中,我有webpack.config.base.ts

In my root I have 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

I then have two projects each with their own 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;

这一切都很好. 这是该工厂的完整示例getConfig = () => {}样式.

This all works absolutely fine. Here's a full example of this factory getConfig = () => {} style.

我的问题是当我尝试更改以更改

My problem is when I try to change to change

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

到es6导入. VS代码甚至提供了建议.

To an es6 import. This is even provided as a suggestion by VS code.

应用此更改后,我会得到

When I apply this change I get

这是我的tsconfig.json,我已经启用了[allowSyntheticDefaultImports][5].建议在此处.

Here's my tsconfig.json I already have [allowSyntheticDefaultImports][5] enabled. Suggested 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.它仍然失败.

But I added export default getConfig; anyway... and npm run build again. It still fails.

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

在把头砸向桌子之前,我最后的尝试是改变

My final attempt before smashing my head into the table was to change

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的意义是什么.更不用说它也不是血腥的工作(与以前一样的问题)

Delete the export default getConfig; in the webpack.config.base.ts and export the const getConfig directly as export const getConfig. But at that point what's the point of module.exports = getConfig. Not to mention it also doesn't bloody work (same issue as before)

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"

What am I missing here? Why can't I simply replace const getConfig = require("../../webpack.config.base"); with import getConfig from "../../webpack.config.base"

PS.

这是我运行此文件的"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",

推荐答案

什么起作用?

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

What does work?

I configured webpack with TypeScript for multiple environments (e.g. development and production) with a common base configuration. To do so, I utilize:

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

假设以下目录结构:

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

其他目录结构(例如您的示例中的两个嵌套项目)也将正常工作.虽然,您可能必须调整以下示例中使用的路径.

Other directory structures (such as two nested projects as in your example) will work as well. Although, you may have to adapt the paths used in the examples below.

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

The base configuration of webpack, webpack.common.ts, looks as follows:

import webpack from 'webpack';

const configuration: webpack.Configuration = {
  // Your common webpack configuration...
};

export default configuration;

针对不同环境的两个Webpack配置使用 npm软件包webpack-merge .您可以在 npm软件包@types/webpack-merge 中找到TypeScript的类型.为了坚持最初的示例,development环境的webpack配置如下所示:

The two webpack configurations for different environments extend this base configuration using the npm package webpack-merge. You can find its typings for TypeScript in the npm package @types/webpack-merge. To stick with the initial example, the webpack configuration for the development environment looks as follows:

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;

与此同时,就import/export语法而言,production环境的webpack配置与development环境所使用的webpack配置没有区别.

Meanwhile, the webpack configuration for the production environment is no different to the one used for the development environment in terms of import/export syntax.

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

As you may have noticed, I use the ES6 import/export syntax:

export default configuration;

import commonWebpackConfiguration from './webpack.common';

因此,所涉及的导入和导出(例如module.exportsrequire)没有 CommonJS 语法,可以使webpack配置文件保持整洁并允许无缝的工作流程.实际上,根据 webpack的文档.

Consequently, there is no CommonJS syntax for imports and exports (e.g. module.exports or require) involved which keeps the webpack configuration files clean and allows for a seamless workflow. This is actually the recommended way to work with webpack and TypeScript as per webpack's documentation.

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

导入es6. VS代码甚至提供了建议.

to an es6 import. This is even provided as a suggestion by VS code.

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

module.exports does indeed not have a default export (i.e. the object module.exports does not have any property named default) as the error you observed stated.
Using ES6 default export (i.e. export default) actually creates an export named default just like for other named exports (e.g. bar in the following). This can be illustrated compiling the following TypeScript snippet:

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

export default helloWorld;
export { bar };

使用tsc到JavaScript:

to JavaScript using tsc:

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

第二次尝试

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

In this case, adding allowSyntheticDefaultImports (which you already have) and esModuleInterop (which you miss) to your TypeScript configuration tsconfig.json both set to true would remedy that issue .

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的意义是什么.

Delete the export default getConfig; in the webpack.config.base.ts and export the const getConfig directly as export const getConfig. But at that point what's the point of module.exports = getConfig.

拥有

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

module.exports = getConfig;

同时

会给您base === getConfig(因为只有module.exports = getConfig;生效).因此,由于定义的函数getConfig没有属性getConfig,因此调用base.getConfig会给出undefined.因此,"base.getConfig不是函数".

at the same time, will give you base === getConfig (as only module.exports = getConfig; takes effect). Consequently, calling base.getConfig gives undefined since your defined function getConfig does not have a property getConfig. Hence, "base.getConfig is not a function".

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

CommonJS 导入,而

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

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

is an ES6 import. They cannot be used interchangeable since they are inherently different. You should choose to work with one of them, but not both at the same time.

这篇关于在TypeScript中使用webpack.config.ts的es6 import进行Module.exports的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!