javascript - Typescript w Webpack import Legacy javascript class_1.class 不是构造函数

标签 javascript typescript webpack ecmascript-6 babeljs

我有一个项目,正在从 Javascript 迁移到 Typescript。有很多旧版 Javascript 以前没有设置为导出/导入,而只是连接在一起。我正在尝试将旧版 Javascript 类导入到 Typescript 代码中,但在尝试创建导入的 javascript 类的新实例时遇到错误。

我正在使用 Webpack 构建最终的 app.js 文件。 Babel 正在 Webpack 中运行。

目录结构:

webpack.config.js
tsconfig.json
.babelrc
legacy-js/
--LegacyJSClass.js
new-ts/
--NewTSClass.ts
ts-build/
--legacy-js/
----LegacyJSClass.js
----LegacyJSClass.js.map
--new-ts/
----NewTSClass.js
----NewTSClass.js.map
dist/
--webpack-output-file.js

./legacy-js/LegacyJSClass.js:

class LegacyJSClass {
    constructor(data) {
        data = data || {};
        this.ExampleJsProp = data.ExampleProp;
    }
}

export { LegacyJSClass };

./new-ts/NewTSClass.ts

import { LegacyJSClass } from "../legacy-js/LegacyJSClass";

export class NewTSClass {
    ExampleTsProp: any = new LegacyJSClass();
    constructor() {
        console.log(this.ExampleTsProp);
    }
}

let tsClass = new NewTSClass();

./tsconfig.json

{
  "compilerOptions": {
    "outDir": "./ts-build",
    "sourceMap": true,
    "noImplicitAny": true,
    "module": "commonjs",
    "target": "es5",
    "allowSyntheticDefaultImports": true,
    "allowJs": true,
    "traceResolution": true
  },
  "compileOnSave": true,
  "include": [
    "./new-ts/**/*"
  ],
  "exclude": [
    "node_modules"
  ]
}

./webpack.config.js

var webpack = require('webpack');
var ManifestPlugin = require('webpack-manifest-plugin');

module.exports = {
    name: 'app',
    devtool: 'inline-source-map',
    plugins: [
        new ManifestPlugin()
    ],
    module: {
        preLoaders: [
            {
                test: /\.js%/,
                loader: 'eslint',
                exclude: /node_modules/
            },
            {
                test: /\.js$/,
                loader: 'source-map-loader',
                exclude: /node_modules/
            }
        ],
        loaders: [
            {
                test: /\.ts?$/,
                loader: 'awesome-typescript-loader',
                exclude: /node_modules/
            },
            {
                test: /\.js$/,
                exclude: /node_modules/,
                loader: "babel-loader",
                options: {
                    presets: ['env']
                }
            }
        ]
    },
    resolve: {
        extensions: [".ts", ".js"]
    },
    entry: __dirname + '/new-ts/NewTSClass',
    output: {
        filename: 'webpack-output-file.js',
        path: __dirname + '/dist'
    },
    eslint: {
        failOnWarning: false,
        failOnError: true
    },
    externals: {
        "jquery": "jquery"
    }
};

./.babelrc

{
  "presets": [ "env" ],
  "plugins": [
    "transform-remove-export" // This removes the export statements from the LegacyJS since it is still contatenated together and output as one big file and doesn't use a module loader.
  ]
}

一切都正确编译,但是当我尝试在浏览器中加载 webpack-output-file.js 时,它给了我错误:

NewTSClass.ts:20 Uncaught TypeError: LegacyJSClass_1.LegacyJSClass is not a constructor
    at new NewTSClass (NewTSClass.ts:20)
    at Object.<anonymous> (NewTSClass.ts:26)
    at __webpack_require__ (bootstrap 4a128ff…:19)
    at Object.defineProperty.value (bootstrap 4a128ff…:39)
    at bootstrap 4a128ff…:39

经过进一步调查,Typescript 似乎正在正确地移动所有内容:

./ts-build/legacy-js/LegacyJSClass.js

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var LegacyJSClass = (function () {
    function LegacyJSClass(data) {
        data = data || {};
        this.ExampleJsProp = data.ExampleProp;
    }
    return LegacyJSClass;
}());
exports.LegacyJSClass = LegacyJSClass;
//# sourceMappingURL=LegacyJSClass.js.map

./ts-build/new-ts/NewTSClass.js

"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var LegacyJSClass_1 = require("../legacy-js/LegacyJSClass");
var NewTSClass = (function () {
    function NewTSClass() {
        this.ExampleTsProp = new LegacyJSClass_1.LegacyJSClass();
        console.log(this.ExampleTsProp);
    }
    return NewTSClass;
}());
exports.NewTSClass = NewTSClass;
var tsClass = new NewTSClass();
//# sourceMappingURL=NewTSClass.js.map

但是,当它们通过 Webpack/babel 运行时......它们的转换方式不同:

./dist/webpack-output-file.js

/*****/

//Webpack Bootstrap 内容...

/******/ ([
/* 0 */
/***/ (function(module, exports, __webpack_require__) {

    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    var LegacyJSClass_1 = __webpack_require__(1);
    var NewTSClass = (function () {
        function NewTSClass() {
            this.ExampleTsProp = new LegacyJSClass_1.LegacyJSClass();
            console.log(this.ExampleTsProp);
        }
        return NewTSClass;
    }());
    exports.NewTSClass = NewTSClass;
    var tsClass = new NewTSClass();

/***/ }),
/* 1 */
/***/ (function(module, exports) {
    "use strict";

    var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();

    function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

    var LegacyJSClass = function LegacyJSClass(data) {
        _classCallCheck(this, LegacyJSClass);

        data = data || {};
        this.ExampleJsProp = data.ExampleProp;

    };

/***/ })
/******/ ]);
// Sourcemap info...

我已经尝试了我能找到的所有不同方法,但无法使其发挥作用。如果我将 js 模块导出更改为 export default LegacyJSClass ,则会出现错误 LegacyJSClass_1.default is not a constructor

最终,我希望它起作用的原因是因为我不想为每个使用的遗留类创建定义的类型文件,并且有太多的类型文件无法立即移植到 typescript 。应用程序的其余部分仍然使用旧版 js,因此在新的 Typescript 正在开发并慢慢发布的同时,它必须继续工作。

最佳答案

您正在使用babel-plugin-transform-remove-export ,这会删除 JavaScript 文件中的所有导出以及 .babelrc 中的注释使用 webpack 时不正确(它可能是旧构建系统的剩余部分)。 Webpack 使用实际的导出,只是 webpack 提供了导出对象以使其在浏览器中工作。您尝试使用的导入在 babel 处理过的模块中不存在,正如您在 webpack 输出中看到的那样,模块 1 中没有导出。如果您尝试注销 LegacyJSClass在你的 TypeScript 文件中,你会看到它是 undefinedundefined不是构造函数(坦率地说,错误消息信息不是很丰富)。

您必须从 .babelrc 中删除该插件并且您也不需要在 babel-loader 上的 webpack 配置中再次配置预设。 ,因为它将使用 .babelrc .

{
  "presets": [ "env" ]
}

关于javascript - Typescript w Webpack import Legacy javascript class_1.class 不是构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43942688/

相关文章:

JavaScript 函数比较数组中的值并返回它

typescript - Create-react-app + react-app-rewired + typescript + antd

webpack - 导入的 scss 类名转换为哈希

javascript - 如何过滤从当前日期到 90 天前的createdAt?

javascript - 我可以让 SignalR 在设置窗口位置时不自行断开连接吗?

javascript - 在父级中使用 Object.assign 设置子属性

reactjs - 如何部署具有代码拆分的 JS 应用程序,确保过去的应用程序版本不会中断

angularjs - Webpack ngTemplate-loader 不会将我的模板包含到 bundle 中 : how to debug?

javascript - 如何使用 JavaScript/RegEx 将 2 个 RegEx 语句组合在一起?

性能问题 - Chutzpah Console.exe 和 TypeScript