Webpack 4,Vue如何同时使用TypeScript类和JS代码?

5
我正在将JS文件迁移到Typescript,并且我的目标是能够在Vue中使用JS和Typescript类。我知道我可以将Vue脚本转换为Typescript,但现在我不想这样做。问题出现在component.vue文件中:
this.exceptionHandler = app.resolve('ExceptionHandler');

浏览器控制台中显示的错误是这样的(编译没有问题):
"TypeError: Cannot call a class as a function"

ExceptionHandler 是在 TypeScript 的 .ts 文件中定义的。

问题是:是否可以先将 TS 代码转译为 JS ES6,然后将代码放在一起,然后对所有内容运行 Babel 将其编译为 ES5?

我在 TS 配置中使用了这些选项:

"lib": ["es7", "es6", "es5", "dom"],
"types": ["reflect-metadata"],
"module": "commonjs",
"target": "es6",

以下是 Webpack 4 的配置:

        {
            test: /\.ts(x?)$/,
            loader: 'babel-loader?presets[]=es2015!ts-loader',
            exclude: [
                "node_modules",
                "vendor",
                "app",
                "public"
            ]
        },

当我只使用ts-loader时,代码可以正常运行,但编译后的JS代码版本是ES6而不是ES5。


1
你需要切换到 Babel 7 才能使其正常工作。此外,使用 @babel/preset-env 替代已弃用的 preset-es2015。我还建议在混合环境中让 Babel 进行 TypeScript 编译。 - connexo
Connexo,谢谢,让我试一下。至少我知道这是可能的。我从一些在线示例中复制了“预设”,但它并不能做我所需要的。没有任何额外的设置,它会起作用吗? - Peter Matisko
1个回答

2
这对于那些刚接触 Webpack 4 的人可能会有所帮助。我的工作 webpack 配置文件如下所示:
const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");


let devMode = process.env.NODE_ENV === 'development';

let webUrl = 'http://my-project.localhost/';
if (process.env.NODE_ENV === 'production') {
    webUrl = 'https://my-project.com/';
}
else if (process.env.NODE_ENV === 'development') {
    webUrl = 'http://my-project.localhost/';
}

module.exports = {
    mode: 'development',
    devtool: 'inline-source-map',
    entry: {
        'frontApps': './resources/assets/js/frontApps.ts',
        'backAppsAdmin': './resources/assets/js/backAppsAdmin.ts',
        'styles' : './resources/assets/sass/styles.scss',
        'adminBack' : './resources/assets/sass/admin back/adminBack.scss',
    },
    module: {
        rules: [

            {
                test: /\.(js|jsx)$/,
                exclude: /(node_modules|bower_components)/,
                use: [{
                    loader: "babel-loader",
                    options: {
                        presets: ['@babel/preset-env']
                    }
                }]
            },

            {
                test: /\.vue$/,
                loader: 'vue-loader',

                options: {
                    loaders: {
                        js: 'babel-loader',

                        css: ExtractTextPlugin.extract({
                            use: [
                                {
                                    loader: 'css-loader',
                                    options : {
                                        url: false
                                    }
                                }
                            ],
                            fallback: 'vue-style-loader',
                       }),
                    }
                }
            },

            {
                test: /\.ts(x?)$/,
                loader: 'babel-loader?presets[]=@babel/preset-env!ts-loader',
                exclude: [
                    "node_modules",
                    "vendor",
                    "app",
                    "public"
                ]
            },

            {
                test: /\.(sa|sc|c)ss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    {
                        loader: 'css-loader',
                        options : {
                            url : false,
                            sourceMap: devMode
                        }
                    },
                    {
                        loader: 'sass-loader',
                        options : {
                            processCssUrls : false,
                            sourceMap: devMode
                        }
                    }
                ],
            }
        ]
    },
    output : {
      filename : 'js/[name].js',
      chunkFilename: 'js/[name].js',
      path: path.resolve(__dirname, 'public'),
      publicPath: webUrl,
    },

    optimization: {
        splitChunks: {
            cacheGroups: {
                vendor : {
                    test : '/node_modules/',
                    chunks: 'all',
                    name: 'vendor',
                    priority: 10,
                    enforce: true
                }
            }
        },
    },

    resolve: {
        extensions: [ '.tsx', '.ts', '.js', '.vue' ],
        alias: {
            vue: 'vue/dist/vue.esm.js'
        }
    },

    plugins: [
        new VueLoaderPlugin(),

        new MiniCssExtractPlugin({
            filename: "css/[name].css",
            chunkFilename: "css/[id].css"
        }),

        new webpack.ProvidePlugin({
            $: 'jquery',
            jQuery: 'jquery'
        }),

        new webpack.ProvidePlugin({
            'regeneratorRuntime': 'regenerator-runtime/runtime'
        }),
    ]
};

如果您想在单文件Vue组件中使用SCSS,请使用以下方法:
<style lang="scss" type="text/scss"  scoped>

</style>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接