本文介紹瞭如何從0開始搭建一個vue+webpack4+typescript項目css
github地址:https://github.com/seanffy/vue-webpack4-TypeScripthtml
使用vue init webpack project建立一個vue+webpack3+js的項目。
vue
將webpack、webpack-dev-server升級到最新版本,其次安裝webpack-cli更新最新版本使用。
npm install webpack@latest —save-dev
node
npm install加載依賴包,運行npm run dev會報錯
此時咱們須要更新html-webpack-plugin。再次運行會報eslint錯誤,關閉eslint規則,在webpack.base.conf.js把createLintingRule()去掉便可
從新運行
須要升級vue-loader,使用npm install vue-loader@latest —save-dev
升級完成以後再webpack.base.conf.js中添加webpack
const { VueLoaderPlugin } = require('vue-loader') module.exports = { mode : 'none', // 有development跟production、none三種狀況,webpack4若是不設置打包完成會報錯,若是有qa或者pl環境能夠設置爲none *** plugins: [ new VueLoaderPlugin() ], *** }
開發環境升級完成ios
首先在prod環境中添加mode:’none’或者mode:’production’
用optimization代替之前的webpack.optimize.CommonsChunkPlugin、uglifyjs-webpack-plugin、webpack.optimize.ModuleConcatenationPlugingit
const webpackConfig = merge(baseWebpackConfig, { // ... mode: 'production', // webpack4 內置 optimization: { splitChunks: { cacheGroups: { vendors: { test: /[\\/]node_modules[\\/]/, chunks: 'initial', name: 'vendors', }, 'async-vendors': { test: /[\\/]node_modules[\\/]/, minChunks: 2, chunks: 'async', name: 'async-vendors' } } }, runtimeChunk: { name: 'runtime' } }, }
從新打包,報錯
extract-text-webpack-plugin插件有問題,推薦使用mini-css-extract-plugin,修改webpack.prod.conf.js和util.js配置github
//webpack.prod.conf.js // const ExtractTextPlugin = require('extract-text-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') // ... // extract css into its own file // new ExtractTextPlugin({ // ... // }) // 升級 webpack4, 由 ExtractTextPlugin 改用 MiniCssExtractPlugin new MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[contenthash].css'), allChunks: true, }), //util.js // const ExtractTextPlugin = require('extract-text-webpack-plugin') const MiniCssExtractPlugin = require('mini-css-extract-plugin') // generate loader string to be used with extract text plugin function generateLoaders (loader, loaderOptions) { const loaders = options.usePostCSS ? [cssLoader, postcssLoader] : [cssLoader] if (loader) { loaders.push({ loader: loader + '-loader', options: Object.assign({}, loaderOptions, { sourceMap: options.sourceMap }) }) } // Extract CSS when that option is specified // (which is the case during production build) // if (options.extract) { // return ExtractTextPlugin.extract({ // use: loaders, // fallback: 'vue-style-loader' // }) // } else { // return ['vue-style-loader'].concat(loaders) // } // 升級 webpack4, 由 ExtractTextPlugin 改用 MiniCssExtractPlugin return [ options.extract ? MiniCssExtractPlugin.loader : 'vue-style-loader', ].concat(loaders) }
打包完成,完成將webpack3升級到webpack4web
安裝vue的官方插件vue-router
npm i vue-class-component vue-property-decorator --save // ts-loader typescript 必須安裝,其餘的相信你之後也會裝上的 npm i ts-loader typescript tslint tslint-loader tslint-config-standard --save-dev
配置webpack
./build/webpack.base.conf.js,將entry.app中的main.js改爲main.ts,順便把項目文件中的main.js改爲main.ts
entry: { app: './src/main.ts' }
找到resolve.extensions 裏面加上.ts 後綴 (是爲了以後引入.ts的時候不寫後綴)
resolve: { extensions: ['.js', '.vue', '.json', '.ts'], alias: { '@': resolve('src') } }
找到module.rules 添加webpack對.ts的解析
module: { rules: [ { // 添加tslint test: /\.ts$/, exclude: /node_modules/, enforce: 'pre', loader: 'tslint-loader' }, { // 添加tsloader test: /\.tsx?$/, loader: 'ts-loader', exclude: /node_modules/, options: { appendTsSuffixTo: [/\.vue$/], } }, ] }
添加tsconfig.js
{ "include": [ "src/**/*" ], "exclude": [ "node_modules" ], "compilerOptions": { "allowSyntheticDefaultImports": true, "experimentalDecorators": true, "allowJs": true, "module": "esnext", "target": "es5", "moduleResolution": "node", "isolatedModules": true, "lib": [ "dom", "es5", "es2015.promise" ], "sourceMap": true, "pretty": true } }
添加tslint.json
{ "extends": "tslint-config-standard", "globals": { "require": true } }
讓ts識別.vue
因爲ts默認並不支持*.vue後綴的文件,因此在vue項目中引入的時候須要建立一個vue-shim.d.ts文件,擋在項目對應使用目錄下,例如
// src/vue-shim.d.ts declare module "*.vue" { import Vue from "vue"; export default Vue; }
意思是告訴 TypeScript *.vue 後綴的文件能夠交給 vue 模塊來處理。
而在代碼中導入 .vue 文件的時候,須要寫上 .vue 後綴。緣由仍是由於 TypeScript 默認只識別 .ts 文件,不識別 *.vue 文件
import Component from 'components/component.vue'
改造.vue文件
<template> <div id="app"> <img src="./assets/logo.png"> <router-view/> </div> </template> <script lang="ts"> import Vue from 'vue' import Component from 'vue-class-component' @Component({}) export default class App extends Vue { } </script> <style> </style>
七、將router下的index.js換成index.ts
import Vue from 'vue' import Router from 'vue-router' import HelloWorld from '@/components/HelloWorld.vue' Vue.use(Router) export default new Router({ routes: [ { path: '/', name: 'HelloWorld', component: HelloWorld } ] })
使用npm run dev 運行項目成功。
可是這裏有個問題就是當前文件是.vue文件,使用ts會有一個錯誤提示
因此這裏想着把ts跟html文件分開,使用.ts後綴文件,拿App.vue舉例說明
首先建立App.html文件
而後建立App.ts文件
使用npm run dev會報錯
提示當前沒有獲取到template的html文件
這時須要配置一個raw-loader將當前.html文件展現在template上,使用npm install raw-loader@latest —save-dev
// webpack.base.conf.js { test: /\.html$/, loader: "raw-loader", exclude: [/.\/src\/index.html/], }
配置完成npm run dev 運行項目,根據當前raw-loader版本不一樣可能會報錯
若是報錯須要更改一下.html的require方式,更改成
require(‘./App.html’).default
至此完成vue+webpack4+typescript搭建項目
當咱們搭建完成項目以後,可能會想在vue.prototype上綁定例如$axios等方法,這時咱們使用之前的方法
import axios from ‘axios’ Vue.prototype.$axios = axios;
當咱們使用this.$axios時會報錯
這時,咱們須要在src目錄下建立一個vue-shim.d.ts文件,添加以下內容便可
// 在 types/vue.d.ts 裏 Vue 有構造函數類型 declare module 'vue/types/vue' { // 3. 聲明爲 Vue 補充的東西 interface Vue { $axios: any } }
Vue官網上個對此有解釋
https://cn.vuejs.org/v2/guide...