目录
1:webpack5 之 构建vue3 + js
package.json
"devDependencies": {
"@vue/compiler-sfc": "^3.2.38",
"vue-loader": "^17.0.0",
"vue-template-compiler": "^2.7.10",
"webpack": "^5.67.0",
"webpack-cli": "^4.9.2",
"webpack-dev-server": "^4.10.1",
"webpack-merge": "^4.2.1",
},
"dependencies": {
"vue": "^3.2.38",
"vue-style-loader": "^4.1.3"
},
webpack.base.js
- VueLoaderPlugin 使用
const path = require('path')
const MiniCssExtract = require('mini-css-extract-plugin') // css提取
const { VueLoaderPlugin } = require('vue-loader')
module.exports = {
entry: {
main: './src/main.js'
},
output: {
publicPath: '',
path: path.resolve(__dirname, '../dist'),
filename: 'js/[name]_[contenthash:6].js',
},
// loader相关配置
module: {
rules: [{
test: /\.(scss|css)$/, // 针对 .scss 或者 .css 后缀的文件设置 loader
use: [
// env.development ? 'style-loader' :
// 'vue-style-loader',
{
loader: MiniCssExtract.loader
},
'css-loader',
'postcss-loader',
'sass-loader' // 使用 sass-loader 将 scss 转为 css
]
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
resolve: {
extensions: ["*", ".js", ".vue"],
// 设置别名
alias: {
"@": path.resolve(__dirname, "../src"), // 这样配置后 @ 可以指向 src 目录
},
},
plugins: [
new VueLoaderPlugin()
]
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head><body>
<div id="app"></div>
</body>
</html>
main.js
import "@/css/main.css"
import "@/css/main.scss"
console.log("main.js-11");
let a = 100;
console.log("a", a);
const set = new Set([1, 2, 3, 1])
console.log('res,', set, '; set-arr', [...set])
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
src / App.vue
<template>
<div class="app">
App
<div class="tt">我是ttt</div>
<Test></Test>
</div>
</template>
<script>
import Test from "./components/Test.vue"
export default {
name: 'App',
components: {
Test
},
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss">
html,
body,
#app {
width: 100%;
height: 100%;
background: pink;
}
.app {
width: 100%;
height: 100%;
background: red;
}
.tt {
color: #fff;
}
</style>
src / components / App.vue
<template>
<div class="test">Test</div>
</template>
<script>
export default {
name: 'Test',
components: {},
data() {
return {}
},
methods: {}
}
</script>
<style lang="scss" scoped>
.test {
background: pink;
font-size: 20px;
}
</style>
注意点 VSCode 报错:找不到模块“./App.vue”或其相应的类型声明。ts(2307)
- 则需要 jsconfig.json ( 项目根目录下创建 )
{
"compilerOptions": {
"baseUrl": "./",
"paths": {
"@/*": ["src/*"]
}
},
"exclude": ["node_modeules", "dist"]
}
效果
-
npm run dev
-
npm run build
2:webpack5 之 构建vue3 + ts
package.json
# 安装以下依赖 --save-dev
# webpack 相关 webpack、webpack-cli
babel-loader
# babel 核心
@babel/core
# 智能转换成目标运行环境代码
@babel/preset-env
# 解析 typescript 的 babel 预设
@babel/preset-typescript
# polyfill
@babel/plugin-transform-runtime
# 支持 ts 类的写法
@babel/plugin-proposal-class-properties
# 支持三点展开符
@babel/plugin-proposal-object-rest-spread
# ts相关
ts-loader
typescript
# vue相关
@vue/compiler-sfc
vue-loader
vue-template-compiler
# 安装以下依赖 --save
@babel/runtime
@babel/runtime-corejs3
"core-js": "^3.11.0",
vue
"devDependencies": {
"@babel/core": "^7.18.13",
"@babel/plugin-proposal-class-properties": "^7.18.6",
"@babel/plugin-proposal-object-rest-spread": "^7.18.9",
"@babel/plugin-transform-runtime": "^7.18.10",
"@babel/preset-env": "^7.18.10",
"@babel/preset-typescript": "^7.18.6",
"@vue/compiler-sfc": "^3.2.38",
"babel-loader": "^8.2.5",
"babel-plugin-import": "^1.13.3",
"ts-loader": "^9.3.1",
"typescript": "^4.8.2",
"vue-loader": "^17.0.0",
"vue-template-compiler": "^2.7.10",
"webpack": "^5.67.0",
"webpack-cli": "^4.9.2"
},
"dependencies": {
"@babel/runtime": "^7.18.9",
"@babel/runtime-corejs3": "^7.18.9",
"core-js": "^3.11.0",
"vue": "^3.2.38",
},
babel.config.js
const presets = [
[
"@babel/preset-env",
{
"useBuiltIns": 'usage', //按需引入 polyfill
"corejs": "3.11.0", // 指定 corejs 版本
targets: {
chrome: '60',
firefox: '60',
ie: '9',
safari: '10',
edge: '17',
},
}
],
// 引用Typescript插件
[
"@babel/preset-typescript",
{
allExtensions: true, //支持所有文件扩展名
"isTSX": true, // 必须设置,否者编译tsx时会报错
"allExtensions": true // 必须设置,否者编译.vue 文件中ts 代码会报错
},
],
]
const plugins = [
[
'@babel/plugin-transform-runtime',
{
corejs: 3,
},
],
'@babel/proposal-class-properties',
'@babel/proposal-object-rest-spread',
]
module.exports = {
plugins,
presets
}
webpack.base.js
- 修改入口文件 .ts
- 添加 .ts文件的解析
const path = require('path')
const {
VueLoaderPlugin
} = require('vue-loader')
module.exports = {
entry: {
main: './src/main.ts'
},
output: {
publicPath: '',
path: path.resolve(__dirname, '../dist'),
filename: 'js/[name]_[contenthash:6].js',
},
// loader相关配置
module: {
rules: [{
test: /\.(scss|css)$/, // 针对 .scss 或者 .css 后缀的文件设置 loader
use: [
// env.development ? 'style-loader' :
// 'vue-style-loader',
{
loader: MiniCssExtract.loader
},
'css-loader',
'postcss-loader',
'sass-loader' // 使用 sass-loader 将 scss 转为 css
]
},
{
// test: /\.(t|j)s$/,
test: /\.js$/,
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
},
{
loader: 'thread-loader',
options: {
workers: 3,
}
}
],
exclude: /node_modules/
},
{
test: /\.ts$/,
loader: "babel-loader",
exclude: /node_modules/,
},
{
test: /\.vue$/,
loader: 'vue-loader'
}
]
},
plugins: [
new VueLoaderPlugin(),
]
}
main.ts
import "@/css/main.css"
import "@/css/main.scss"
console.log("main.js-11");
let a = 100;
console.log("a", a);
// const set = new Set([1, 2, 3, 1])
// console.log('res,', set, '; set-arr', [...set])
import "./ts/test.ts"
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')
ts / test.ts
//2;number类型
let num: number = 123
// num = "pin"; //出错
console.log('ts-num',num) //123
//3:定义数组
let arr: number[] = [1, 3, 5, 7]
let arr2: string[] = ['pink', 'lala', 'pa']
console.log('ts-arr',arr2) //["pink", "lala", "pa"]
App.vue
<template>
<div class="app">
App
<div class="tt">我是ttt</div>
<Test></Test>
<div>a - {{ a }}</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Test from './components/Test.vue'
const a = ref(0)
</script>
<script lang="ts">
export default {
name: 'App'
}
</script>
<style lang="scss">
html,
body,
#app {
width: 100%;
height: 100%;
}
.app {
width: 100%;
height: 100%;
background: red;
}
.tt {
color: #fff;
}
</style>
conponets / Test.vue
<!-- -->
<template>
<div>Test - vue3.2</div>
</template>
<script setup lang="ts">
import {} from 'vue'
</script>
<script lang="ts">
export default {
name: 'Test'
}
</script>
<style lang="scss" scoped></style>
tsconfig.json
{
"include":["./src/**/*"],
"compilerOptions": {
"module": "commonjs",
"sourceMap": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"strict": true,
"skipLibCheck": true
}
}
效果
-
npm run dev
-
npm run build
3:webpack5 之 构建vue3 + ts + vue-route
找不到模块“@/views/home/Home.vue”或其相应的类型声明。ts(2307)
- 再src 下 创建 vue.d.ts 文件
declare module '*.vue' {
import Vue from '@/vue'
export default Vue
}
package.json
"dependencies": {
"vue": "^3.2.38",
"vue-router": "^4.1.5"
},
router / index.ts
- 路由文件的设置
import {
createRouter,
createWebHistory,
createWebHashHistory
} from 'vue-router'
// 静态路由
export const constantRoutes = [
{
path: '/',
redirect: '/home'
},
{
path: '/home',
name: 'Home',
component: () => import(/* webpackChunkName: "Home" */'@/views/home/Home.vue'),
meta: { hidden: true }
},
{
path: '/about',
component: () => import(/* webpackChunkName: "About" */'@/views/about/About.vue'),
meta: { hidden: true }
}
]
// history: createWebHistory(import.meta.env.BASE_URL),
const router = createRouter({
history: createWebHashHistory(),
routes: constantRoutes,
// 刷新时,滚动条位置还原
scrollBehavior: () => ({ left: 0, top: 0 })
})
export default router
main.ts
- 引入路由 并且挂载到vue
import '@/css/main.css'
import '@/css/main.scss'
console.log('main.js-11')
let a = 100
console.log('a', a)
import './ts/test.ts'
import { createApp } from 'vue'
import router from './router'
import App from './App.vue'
const app = createApp(App)
app.use(router)
app.mount('#app')
App.vue
- 为路由添加 入口
<template>
<div class="app">
<router-link to="/">首页</router-link>
<router-link to="/about">关于</router-link>
<router-view></router-view>
<div>
App文件
<div class="tt">我是ttt</div>
<Test></Test>
<div>a - {{ a }}</div>
</div>
</div>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import Test from './components/Test.vue'
const a = ref(0)
</script>
<script lang="ts">
export default {
name: 'App'
}
</script>
<style lang="scss">
html,
body,
#app {
width: 100%;
height: 100%;
}
.app {
width: 100%;
height: 100%;
background: #fff;
overflow: hidden;
}
.tt {
color: #fff;
}
</style>
效果
- npm run dev | build 效果
- 一开始 默认加载 home页面,点击关于 - 跳转到关于页面,点击首页,跳转到首页页面
4:webpack5 之 构建vue3 + ts + pinia
package.json
"dependencies": {
"pinia": "^2.0.21",
"vue": "^3.2.38"
},
main.ts
import { createApp } from 'vue'
// 使用 pinia
import { createPinia } from 'pinia'
const pinia = createPinia()
import App from './App.vue'
const app = createApp(App)
app.use(pinia)
app.mount('#app')
store / index.ts
import useAppStore from './modules/app'
import useHomeStore from './modules/home'
const useStore = () => ({
app: useAppStore(),
home: useHomeStore()
})
export default useStore
store / modules / app.ts
// import { AppState } from '@/types/store/app'
import { defineStore } from 'pinia'
const useAppStore = defineStore({
id: 'app',
// state: (): AppState => ({
state: () => ({
count: 0
}),
actions: {
addCount(payload: number) {
this.count = payload
}
}
})
export default useAppStore
store / modules / home.ts
// import { AppState } from '@/types/store/app'
import { defineStore } from 'pinia'
const useHomeStore = defineStore({
id: 'home',
// state: (): AppState => ({
state: () => ({
homeStr: "homeStr",
}),
actions: {
changeHomeStr( payload : string) {
this.homeStr = payload
}
}
})
export default useHomeStore
App.vue
<template>
<div class="app">
<div>pinia的使用</div>
<div>appCount - {{ appCount }}</div>
<div>homeStr - {{ homeStr }}</div>
<button type="primary" @click="btn">Primary</button>
</div>
</template>
<script setup lang="ts">
import { ref, computed } from 'vue'
import Test from './components/Test.vue'
import useStore from '@/store'
const { app, home } = useStore() as any // 拿到 store的数据
const appCount = computed(() => app.count)
const homeStr = computed(() => home.homeStr)
const btn = () => {
app.addCount(10)
home.changeHomeStr('我是hh')
}
</script>
<script lang="ts">
export default {
name: 'App'
}
</script>
<style lang="scss">
html,
body,
#app {
width: 100%;
height: 100%;
}
.app {
width: 100%;
height: 100%;
background: #fff;
overflow: hidden;
}
.tt {
color: #fff;
}
</style>
效果
- npm run dev | build