带有 es6 导入的 Module.exports 用于 typescript 中的 webpack.config.ts
Posted
技术标签:
【中文标题】带有 es6 导入的 Module.exports 用于 typescript 中的 webpack.config.ts【英文标题】:Module.exports with es6 import for webpack.config.ts in typescript 【发布时间】: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",
【问题讨论】:
【参考方案1】:什么有效?
我用 TypeScript 为多个环境(例如 development
和 production
)配置了 webpack 和通用的基本配置。为此,我利用:
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.exports
或 require
),这可以保持 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 导入。它们不能互换使用,因为它们本质上是不同的。您应该选择使用其中之一,但不能同时使用两者。
【讨论】:
以上是关于带有 es6 导入的 Module.exports 用于 typescript 中的 webpack.config.ts的主要内容,如果未能解决你的问题,请参考以下文章
JS模块导入导出规范-CommonJS | ES6 -规范案例
ES6导入导出import | export | export default-使用案例
ES6导入导出import | export | export default-使用案例
module.exports---exports---export default与import---require区别和联系