如何在以Vue为前端的Laravel Project中使用Typescript?

时间:2018-12-05 14:19:16

标签: laravel typescript vue.js

我想在Laravel项目的Vue中使用打字稿。

我已经检查了所有教程,但是没有一个适合我 teejTitas Gailiussebastiandedeyne

每当我运行'npm run dev'时,我都会收到此错误

    ERROR in ./resources/js/app.ts
   Module build failed: Error: You may be using an old version of webpack; please check you're using at least version 4
at successfulTypeScriptInstance (E:\PersonalProjects\web_dev\blog\node_modules\ts-loader\dist\instances.js:144:15)
at Object.getTypeScriptInstance (E:\PersonalProjects\web_dev\blog\node_modules\ts-loader\dist\instances.js:34:12)
at Object.loader (E:\PersonalProjects\web_dev\blog\node_modules\ts-loader\dist\index.js:17:41)
 @ multi ./resources/js/app.ts ./resources/sass/app.scss

1 个答案:

答案 0 :(得分:0)

很长一段时间以来,我都面临着这个问题,但是我终于能够找到解决方案,所以我将我的经验分享给了想要在Laravel中使用typescript而不是javascript的人们。这是说明

此处指示

Laravel 5.7使用Laravel-mix,而后者使用webpack 3。我们不希望打字稿在laravel项目中工作。

初始化您的项目

让我们创建一个新项目。您也可以在现有项目上执行此操作,只需确保将js代码转换为ts。

首先请确保您已安装作曲家和laravel

sh laravel new Laravel-Vue-Typecript 在任何常用的代码编辑器中打开项目。

打开package.json并将这些包添加到devdependencies

{
   "devDependencies": {
        "auto-loader": "^0.2.0",
        "autoprefixer": "^9.4.1",
        "axios": "^0.18",
        "bootstrap": "^4.0.0",
        "lodash": "^4.17.5",
        "popper.js": "^1.12",
        "jquery": "^3.2",
        "cross-env": "^5.1",
        "css-loader": "^1.0.1",
        "mini-css-extract-plugin": "^0.4.5",
        "node-sass": "^4.10.0",
        "optimize-css-assets-webpack-plugin": "^5.0.1",
        "postcss-loader": "^3.0.0",
        "sass-loader": "^7.1.0",
        "ts-loader": "^5.3.1",
        "typescript": "^3.2.1",
        "uglifyjs-webpack-plugin": "^2.0.1",
        "vue": "^2.5.17",
        "vue-class-component": "^6.3.2",
        "vue-property-decorator": "^7.2.0",
        "webpack": "^4.26.1",
        "webpack-cli": "^3.1.2",
        "vue-loader": "^15.4.2",
        "vue-template-compiler": "^2.5.17"
    }
}

现在使用以下命令安装这些npm软件包

npm install

添加打字稿支持

然后重命名这些文件

Laravel-Vue-Typecript/
├─ resources/js/app.js => resources/js/app.ts
└─ resources/js/bootstrap.js => resources/js/bootstrap.ts

现在在app.tsbootstrap.ts

中更改代码

resources / js / components / ExampleComponent.vue

// app.ts
import "./bootstrap"
import Vue from "vue"
import ExampleComponent from "./components/ExampleComponent.vue"

Vue.component('example', ExampleComponent)

new Vue({
    el: '#app'
})



// bootstrap.ts
import axios from 'axios';
import * as _ from 'lodash';
import jQuery from 'jquery';
import * as Popper from 'popper.js';
import 'bootstrap';

axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';


let token : HTMLMetaElement | null = document.head!.querySelector('meta[name="csrf-token"]');

if (token) {
    axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
    console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}


// resources/js/components/ExampleComponent.vue
<template>
    <h1>This is an example component</h1>
</template>

<script lang="ts">
import Vue from 'vue'
import Component from "vue-class-component"
@Component
export default class ExampleComponent extends Vue {
    mounted() : void {
        console.log("hello");
    }
}
</script>

``` 在typings.d.ts内创建resources/js文件,并添加以下行。

declare module '*.vue' {
    import Vue from 'vue'
    export default Vue
}

declare module 'jquery';

declare module 'lodash';

现在在项目的根目录中分别创建tsconfig.jsonwebpack.config.jspostcss.config.js,并分别对这些代码行

tsconfig.json

{
    "compilerOptions": {
        "target": "es5",
        "strict": true,
        "module": "es2015",
        "moduleResolution": "node",
        "experimentalDecorators": true,
        "skipLibCheck": true
    },
    "include": [
        "resources/js/**/*"
    ],
    "exclude": [
        "node_modules",
        "vendor"
    ]
}

webpack.config.json

const path = require('path')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const VueLoaderPlugin = require('vue-loader/lib/plugin')
const autoprefixer = require('autoprefixer');
const webpack = require('webpack');


let env = process.env.NODE_ENV
let isDev = env === 'development'

const WEBPACK_CONFIG = {
    mode: env,
    entry: {
        app: ['./resources/js/app.ts', './resources/sass/app.scss'],
    },
    output: {
        publicPath: './public',
        path: path.resolve(__dirname, 'public'),
        filename: 'js/[name].js',
        chunkFilename: 'js/chunks/app.js'

    },
    module: {
        rules: [{
                test: /\.tsx?$/,
                loader: 'ts-loader',
                options: { appendTsSuffixTo: [/\.vue$/] },
                exclude: /node_modules/,
            },
            {
                test: /\.vue$/,
                loader: 'vue-loader'
            },
            {
                test: /\.scss$/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader',
                    'sass-loader'
                ],
                exclude: /node_modules/,
            }
        ],
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: 'css/[name].css'
        }),
        new VueLoaderPlugin(),
        new webpack.LoaderOptionsPlugin({
            options: {
                postcss: [
                    autoprefixer()
                ]
            }
        })

    ],
    resolve: {
        extensions: ['.js', '.jsx', '.vue', '.ts', '.tsx'],
        alias: {
            vue$: 'vue/dist/vue.esm.js',
        },
    },
    optimization: {
        splitChunks: {
            chunks: 'async',
            minSize: 30000,
            maxSize: 0,
            minChunks: 1,
            maxAsyncRequests: 5,
            maxInitialRequests: 3,
            automaticNameDelimiter: '~',
            name: true,
            cacheGroups: {
                vendors: {
                    test: /[\\/]node_modules[\\/]/,
                    priority: -10
                },
                default: {
                    minChunks: 2,
                    priority: -20,
                    reuseExistingChunk: true
                }
            }
        }
    }


}

if (!isDev) {
    WEBPACK_CONFIG.optimization = {
        minimizer: [
            new UglifyJsPlugin({
                cache: true,
                parallel: true,
                sourceMap: true
            }),
            new OptimizeCSSAssetsPlugin({})
        ]
    }

    WEBPACK_CONFIG.plugins.push(
        new webpack.DefinePlugin({
            'process.env': {
                NODE_ENV: 'production'
            }
        })

    )
}

module.exports = WEBPACK_CONFIG

postcss.config.js

 module.exports = {
     plugins: {
         'autoprefixer': {}
    } }

现在终于更改package.json中的“脚本”

"scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=webpack.config.js"
    },

最终构建项目

并通过运行npm脚本 npm run dev // To build the Project npm run watch // To build and watch for files changes and build automagically npm run prod // for production