webpack5 之 构建vue3+js、vue3+ts、vue3 + vue-route、vue3 + pinia

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
    在这里插入图片描述
    在这里插入图片描述
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值