自定义vue3多页脚手架——模板创建(一)

223 阅读2分钟

准备工作

1、文件夹准备

image.png

tsconfig.json配置

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "strict": true,
    "sourceMap": true,
    "importHelpers": true,
    "moduleResolution": "node",
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "lib": ["esnext", "scripthost"],
    "typeRoots": ["./node_modules/@types", "./src/typings"]
  },
  "exclude": ["node_modules"]
}

2、依赖安装

npm install --save-dev typescript ts-node @types/node @types/webpack @types/webpack-dev-server

webpack基本配置

import {join} from 'path';
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
// import  HtmlWebpackPlugin  =  require('html-webpack-plugin');
export default{
  mode:'development',
  entry:'./src/index.ts',
  // 输出在当前目录下的dist文件夹,文件为index.js
  output:{
    path:join(__dirname,'dist'),
    filename:'[name].js'
  },
  resolve:{
  // 解析后缀名
    extensions:['.ts','.tsx','.vue','.js']
  },
  // 本地服务,不用bulid也能看页面
  devServer:{
    port:9000
  },
  plugins:[
  // 打包先删除dist
    new CleanWebpackPlugin(),
  // 打包创建html
    new HtmlWebpackPlugin({
      title:'home',
      template:'./src/index.html'
    })
  ]
}

vue配置

参考vue-cli手动配置

安装 vue npm i vue

1、webpack.config.js 配置

// webpack.config.js
import { VueLoaderPlugin } from 'vue-loader';
// npm i vue-loader vue-style-loader ts-loader css-loader babel-loader @babel/core @vue/babel-preset-app vue-template-compiler
module.exports = {
  mode: 'development',
  module: {
    rules:[
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      // 它会应用到普通的 `.ts`或`.tsx`文件
      {
        test: /\.tsx?$/,
        use: [
          'babel-loader',            //转tsx用
          {
            loader:'ts-loader',       //转ts用,基于tsconfig.json,转成es6,再用babel-loader转成es5
            options:{                 
              transpileOnly:true,     //只转代码
              appendTsSuffixTo:[/\.vue$/]  
            }
          }
        ]
      },
      // 它会应用到普通的 `.js` 文件
      // 以及 `.vue` 文件中的 `<script>` 块
      {
        test: /\.js$/,
        loader: 'babel-loader'
      },
      // 它会应用到普通的 `.css` 文件
      // 以及 `.vue` 文件中的 `<style>` 块
      {
        test: /\.(scss|sass)$/,
        use: [
          'vue-style-loader',
          'css-loader'
        ]
      }
    ]
  },
  plugins: [
    // 请确保引入这个插件来施展魔法
    new VueLoaderPlugin()
    // esm-bundler需要定义的环境变量
    new webpack.DefinePlugin({
      "__VUE_OPTIONS_API__":true,
      "__VUE_PROD_DEVTOOLS__":false,
    }),
  ]
}

2、使用vue文件

1、新建home.vue

<template>
  <div>{{ title }}</div>
</template>

<script lang="ts">
import { defineComponent, ref } from "vue";
export default defineComponent({
  name: "",
  setup(props, { emit, attrs, slots }) {
    return {
      title: "home",
    };
  },
});
</script>
<style lang="scss" scoped></style>

2、入口文件index.ts

import { createApp }from 'vue'
import Home from './home'

createApp(Home).mount('#home')

在这里我们会遇到ts识别不到vue文件的问题,目前最好用tsx

image.png 但也有解决办法,我们可以通过新建定义文件typings/vue.d.ts来解决

//typings/vue.d.ts
declare module '*.vue'{
  // type表示当成类型引入
  import type { DefineComponent } from "vue";
  const component:DefineComponent<{},{},any>
  export default component;
}

截止目前的完整文件

webpack.config.ts

import {join} from 'path';
import { CleanWebpackPlugin } from 'clean-webpack-plugin';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import { VueLoaderPlugin } from 'vue-loader';
import  webpack  from 'webpack';
export default{
  mode:'development',
  entry:'./src/index.ts',
  // 输出在当前目录下的dist文件夹,文件为index.js
  output:{
    path:join(__dirname,'dist'),
    filename:'[name].js'
  },
  // 解析后缀名
  resolve:{
    extensions:['.ts','.tsx','.vue','.js']
  },
  module:{
    // npm i vue-loader vue-style-loader ts-loader css-loader babel-loader @babel/core @vue/babel-preset-app vue-template-compiler
    rules:[
      {
        test: /\.vue$/,
        loader: 'vue-loader'
      },
      // 它会应用到普通的 `.ts`或`.tsx`文件
      {
        test: /\.tsx?$/,
        use: [
          'babel-loader',            //转tsx用
          {
            loader:'ts-loader',       //转ts用,基于tsconfig.json,转成es6,再用babel-loader转成es5
            options:{                 
              transpileOnly:true,     //只转代码
              appendTsSuffixTo:[/\.vue$/]  
            }
          }
        ]
      },
      // 它会应用到普通的 `.js` 文件
      // 以及 `.vue` 文件中的 `<script>` 块
      {
        test: /\.js$/,
        loader: 'babel-loader'
      },
      // 它会应用到普通的 `.scss` 文件
      // 以及 `.vue` 文件中的 `<style>` 块
      {
        test: /\.(scss|sass)$/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'
        ]
      }
    ]
  },
  // 本地服务,不用bulid也能看页面
  devServer:{
    port:9000
  },
  plugins:[
  // 请确保引入这个插件来施展魔法
    new VueLoaderPlugin(),
  // esm-bundler需要定义的环境变量
    new webpack.DefinePlugin({
      "__VUE_OPTIONS_API__":true,
      "__VUE_PROD_DEVTOOLS__":false,
    }),
  // 删除dist
    new CleanWebpackPlugin(),
  // 创建html
    new HtmlWebpackPlugin({
      title:'home',
      template:'./src/index.html'
    })
  ]
}

package.json

{
  "name": "v3-mutiple-cli",
  "version": "1.0.0",
  "description": "webpack vue3 多页",
  "main": "index.js",
  "scripts": {
    "start": "webpack serve ",
    "build": "webpack"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@babel/core": "^7.17.5",
    "@types/node": "^17.0.18",
    "@types/webpack": "^5.28.0",
    "@types/webpack-dev-server": "^4.7.2",
    "@vue/babel-preset-app": "^5.0.1",
    "babel-loader": "^8.2.3",
    "clean-webpack-plugin": "^4.0.0",
    "css-loader": "^6.6.0",
    "dev-server": "^0.2.0",
    "html-webpack-plugin": "^5.5.0",
    "sass": "^1.49.8",
    "sass-loader": "^12.6.0",
    "style-loader": "^3.3.1",
    "ts-loader": "^9.2.6",
    "ts-node": "^10.5.0",
    "typescript": "^4.5.5",
    "vue-loader": "^17.0.0",
    "vue-style-loader": "^4.1.3",
    "vue-template-compiler": "^2.6.14",
    "webpack-cli": "^4.9.2"
  },
  "dependencies": {
    "vue": "^3.2.31",
    "webpack": "^5.69.1"
  }
}

文件结构

image.png