本文介绍了如何从0开始搭建一个vue+webpack4+typescript项目
github地址:https://github.com/seanffy/vue-webpack4-TypeScript
1、创建项目
使用vue init webpack project创建一个vue+webpack3+js的项目。
2、安装插件
将webpack、webpack-dev-server升级到最新版本,其次安装webpack-cli更新最新版本使用。
npm install webpack@latest —save-dev
3、配置开发环境
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中添加
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
mode : 'none', // 有development跟production、none三种情况,webpack4如果不设置打包完成会报错,如果有qa或者pl环境可以设置为none
***
plugins: [
new VueLoaderPlugin()
],
***
}
开发环境升级完成
4、配置生产环境
首先在prod环境中添加mode:’none’或者mode:’production’
用optimization代替以前的webpack.optimize.CommonsChunkPlugin、uglifyjs-webpack-plugin、webpack.optimize.ModuleConcatenationPlugin
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配置
//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升级到webpack4
5、引入ts
安装vue的官方插件
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>
7、将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搭建项目
6、绑定原型方法
当我们搭建完成项目之后,可能会想在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...
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。