Typescript w Webpack导入旧javascript类_1.class不是构造函数

Typescript w Webpack导入旧javascript类_1.class不是构造函数,javascript,typescript,webpack,ecmascript-6,babeljs,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/ --LegacyJSClas

我有一个项目,我正在从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
class LegacyJSClass {
    constructor(data) {
        data = data || {};
        this.ExampleJsProp = data.ExampleProp;
    }
}

export { LegacyJSClass };
/legacy js/LegacyJSClass.js:

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
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();
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"
    }
};
"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
"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
/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

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

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

let tsClass = new NewTSClass();
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"
    }
};
"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
"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
/.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
/ts build/new ts/NewTSClass.js

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

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

let tsClass = new NewTSClass();
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"
    }
};
"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
"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

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

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

let tsClass = new NewTSClass();
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"
    }
};
"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
"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
/******/

//网页包引导的东西

/******/ ([
/* 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...
/******/([
/* 0 */
/***/(功能(模块、导出、网页包、要求){
“严格使用”;
defineProperty(导出,“\uu esModule”{value:true});
var LegacyJSClass_1=__网页包_要求__(1);
var NewTSClass=(函数(){
函数NewTSClass(){
this.ExampleTsProp=new LegacyJSClass_1.LegacyJSClass();
console.log(this.ExampleTsProp);
}
返回newsclass;
}());
exports.NewTSClass=NewTSClass;
var tsClass=新的NewTSClass();
/***/ }),
/* 1 */
/***/(功能(模块、导出){
“严格使用”;
var_createClass=function(){function defineProperties(target,props){for(var i=0;i
我已经尝试了我能找到的每一种不同的方法,但都无法让它发挥作用。如果我将js模块导出更改为
export default LegacyJSClass
,它将给出错误
LegacyJSClass\u 1。默认值不是构造函数


最终,我想让它工作的原因是,我不想为使用的每个遗留类创建定义的类型文件,而且有太多的类型文件需要立即移植到typescript。应用程序的其余部分仍然使用传统的js,因此在开发和缓慢发布新的Typescript时,它必须继续工作。

您使用的是
babel plugin transform remove export
,它将从JavaScript文件和
中删除所有导出内容。使用webpack时,babelrc
是不正确的(这可能是旧构建系统的遗留问题).Webpack使用实际导出,只是Webpack提供的导出对象使其在浏览器中工作。您尝试使用的导入在babel处理的模块中不存在,正如您在Webpack输出中看到的,模块1中没有导出。如果您尝试在TypeScrip中注销
LegacyJSClass
t文件,您将看到它是
未定义的
,并且
未定义的
不是构造函数(坦率地说,错误消息并不是很有用)

您必须从
.babelrc
中删除插件,并且您也不需要在
babel加载程序的网页配置中再次配置预设,因为它将使用
.babelrc

{
  "presets": [ "env" ]
}

您使用的是
babel plugin transform remove export
,它会从JavaScript文件中删除所有导出,并且
中的注释不正确。使用webpack时,babelrc
是不正确的(它可能是旧构建系统的遗留物).Webpack使用实际导出,只是Webpack提供的导出对象使其在浏览器中工作。您尝试使用的导入在babel处理的模块中不存在,正如您在Webpack输出中看到的,模块1中没有导出。如果您尝试在TypeScrip中注销
LegacyJSClass
t文件,您将看到它是
未定义的
,并且
未定义的
不是构造函数(坦率地说,错误消息并不是很有用)

您必须从
.babelrc
中删除插件,并且您也不需要在
babel加载程序的网页配置中再次配置预设,因为它将使用
.babelrc

{
  "presets": [ "env" ]
}

这是有效的。我不知道如果Web包配置中已经定义了babelrc,那么Web包babel配置将访问我的babelrc。babelrc正由一个包含所有旧JS的旧gulp进程使用。包含导出删除是因为该旧JS没有模块加载程序。我将babel设置直接放在gulp bab中el plugin声明,并从我的babelrc中删除了transform remove export插件,一切都很好。谢谢!这起作用了。我不知道webpack babel配置将访问我的babelrc,如果它已经在webpack配置中定义。babelrc正被旧的gulp进程使用