问题
I am migrating JS files to Typescript and my goal is, to be able to use both JS and Typescript classes in Vue. I know, I can convert Vue scripts into Typescript, but I don't want to do it right now.
The problem arises in a component.vue file:
this.exceptionHandler = app.resolve('ExceptionHandler');
The errror I get in the browser's console is this (compilation is ok):
"TypeError: Cannot call a class as a function"
ExceptionHandler is defined in a TypeScript .ts file.
The question is: Is it possible to first transpile the TS code to JS ES6, then put the code together and then run Babel on everything to compile it to ES5?
I use these options in the TS configuration:
"lib": ["es7", "es6", "es5", "dom"],
"types": ["reflect-metadata"],
"module": "commonjs",
"target": "es6",
And Webpack 4 config:
{
test: /\.ts(x?)$/,
loader: 'babel-loader?presets[]=es2015!ts-loader',
exclude: [
"node_modules",
"vendor",
"app",
"public"
]
},
When I use just ts-loader, the code works well, but the version of the compiled JS code is ES6 and not ES5.
回答1:
This may be useful to those of you new to Webapack 4. My working webpack config file looks like this:
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',
'admin-back' : './resources/assets/sass/admin back/admin-back.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'
}),
]
};
If you want to use SCSS inside a single file Vue components, then use this:
<style lang="scss" type="text/scss" scoped>
</style>
来源:https://stackoverflow.com/questions/52247594/webpack-4-vue-using-typescript-classes-and-js-code-at-the-same-time