This quick start guide will teach you how to get Laravel TypeScript and Vue working together. This guide is flexible enough that any steps here can be used to integrate TypeScript into an existing Laravel project. Sepecfically Laravel 5.7 .
Laravel 5.7 uses Laravel-mix which down the line uses webpack 3 . Which is not what we want for typescript to work in laravel project.
Let's create a new Project.
First make sure you have composer and laravel installed
laravel new Laravel-Vue-Typecript
Open the project in your any favourite code editor.
Open the package.json
and add these packages to dependencies
{
"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",
"clean-webpack-plugin": "1.0.0",
"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"
}
}
Now install these npm packages with
npm install
Then rename these files
Laravel-Vue-Typecript/
├─ resources/js/app.js => resources/js/app.ts
└─ resources/js/bootstrap.js => resources/js/bootstrap.ts
Now Change the Code in app.ts
, bootstrap.ts
and 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>
Create typings.d.ts
file inside resources/js
and add these lines.
declare module '*.vue' {
import Vue from 'vue'
export default Vue
}
declare module 'jquery';
declare module 'lodash';
Now Create tsconfig.json
, webpack.config.js
and postcss.config.js
in the root of your project and these lines of code to them respectivly
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"strict": true,
"module": "es2015",
"moduleResolution": "node",
"experimentalDecorators": true,
"skipLibCheck": true
},
"include": [
"resources/js/**/*"
],
"exclude": [
"node_modules",
"vendor"
]
}
webpack.config.js
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': {}
}
}
Now finally change the "scripts" in 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"
},
and run the npm scripts by
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
This git repo is made possible by some online tutorial teej. Titas Gailius. sebastiandedeyne.