vite+typescript从入门到实战(二)

简介: vite+typescript从入门到实战

vite+typescript从入门到实战(一):https://developer.aliyun.com/article/1483566


设置默认打开的浏览器


设置server.open默认打开的浏览器

/**
 * 设置server.open默认打开的浏览器
 * npm i open -D
 */
const open = require('open');
process.env.BROWSER = open.apps.chrome

gzip 压缩配置

/**
 * gzip 压缩配置
 * npm i vite-plugin-compression -D
 */
import viteCompression from 'vite-plugin-compression'
const viteCompressionOptions = {
    filter: /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i, // 需要压缩的文件
    threshold: 1024, // 文件容量大于这个值进行压缩
    algorithm: 'gzip', // 压缩方式
    ext: 'gz', // 后缀名
    deleteOriginFile: true, // 压缩后是否删除压缩源文件
}

使用mockjs

/**
 * mockjs
 * yarn add -D cross-env vite-plugin-mock
 * yarn add  mockjsD
 */
import { viteMockServe } from 'vite-plugin-mock';
// let prodMock = true;
// const viteMockServeOptions = {
//     mockPath: 'mock',
//     supportTs: false,
//     ignore: undefined,
//     watchFiles: true,
//     localEnabled: command === 'serve',
//     prodEnabled: command !== 'serve' && prodMock,
//     injectCode: `
//     import { setupProdMockServer } from '../mockProdServer';
//     setupProdMockServer();
//   `, // prodEnabled=true生效 main.{ts,js}
//     injectFile: '', // default: path.resolve(process.cwd(),'src/main.{ts,js}')
//     configPath: '', //default: vite.mock.config.ts
//     logger: true, //请求是输入日子
// }

/**
 * yarn add vite-plugin-mock-server
 */
// import mockServer from 'vite-plugin-mock-server'
// vite-plugin-mock-server
// options.plugins.push(mockServer({
//     logLevel: 'info',
//     urlPrefixes: ['/api/'],
//     mockRootDir: './mock',
//     mockJsSuffix: '.mock.js',
//     mockTsSuffix: '.mock.ts',
//     noHandlerResponse404: true,
//     mockModules: []
// }))

完整配置项参数

/**
 * import.meta.env.VITE_x 在.env[mode]中定义的变量不能访问到要用 loadEnv函数代替
 * 
 * 
 * https://github.com/vitejs/awesome-vite#plugins
 */
import { defineConfig, loadEnv } from 'vite'

/**
 * vue 整合插件
 * npm i @vitejs/plugin-vue -D
 */
import vue from '@vitejs/plugin-vue'
const url = require('url')
let parseURL = url.parse('http://user:pass@host.com:8080/p/a/t/h?name=zhangsan&age=12#hash', true, true)

// 解析路径
const path = require('path')

/**
 * 设置server.open默认打开的浏览器
 * npm i open -D
 */
const open = require('open');
process.env.BROWSER = open.apps.chrome


/**
 * gzip 压缩配置
 * npm i vite-plugin-compression -D
 */
import viteCompression from 'vite-plugin-compression'
const viteCompressionOptions = {
    filter: /\.(js|css|json|txt|html|ico|svg)(\?.*)?$/i, // 需要压缩的文件
    threshold: 1024, // 文件容量大于这个值进行压缩
    algorithm: 'gzip', // 压缩方式
    ext: 'gz', // 后缀名
    deleteOriginFile: true, // 压缩后是否删除压缩源文件
}

/**
 * mockjs
 * yarn add -D cross-env vite-plugin-mock
 * yarn add  mockjsD
 */
import { viteMockServe } from 'vite-plugin-mock';
// let prodMock = true;
// const viteMockServeOptions = {
//     mockPath: 'mock',
//     supportTs: false,
//     ignore: undefined,
//     watchFiles: true,
//     localEnabled: command === 'serve',
//     prodEnabled: command !== 'serve' && prodMock,
//     injectCode: `
//     import { setupProdMockServer } from '../mockProdServer';
//     setupProdMockServer();
//   `, // prodEnabled=true生效 main.{ts,js}
//     injectFile: '', // default: path.resolve(process.cwd(),'src/main.{ts,js}')
//     configPath: '', //default: vite.mock.config.ts
//     logger: true, //请求是输入日子
// }

/**
 * yarn add vite-plugin-mock-server
 */
// import mockServer from 'vite-plugin-mock-server'
// vite-plugin-mock-server
// options.plugins.push(mockServer({
//     logLevel: 'info',
//     urlPrefixes: ['/api/'],
//     mockRootDir: './mock',
//     mockJsSuffix: '.mock.js',
//     mockTsSuffix: '.mock.ts',
//     noHandlerResponse404: true,
//     mockModules: []
// }))

// export default ({ command, mode }) => {
//     console.log(command, mode);
export default defineConfig(({ command, mode }) => {
        let options = {
            root: process.cwd(), //项目根目录(index.html 文件所在的位置
            base: '/', //开发或生产环境服务的公共基础路径
            // mode:'development' 'production'
            define: { // 定义全局常量,======待研究怎么用======
                __PBR_APP_VERSION__: '1.0'
            },
            plugins: [vue()], // 需要用到的插件数组
            publicDir: 'public', // 静态资源文件夹,默认访问路径‘/’, 构建是会放在outDir根目录
            cacheDir: 'node_modules/.vite', // vite缓存文件目录,--force可以强制重新缓存
            resolve: {
                alias: { // 别名
                    '@': path.resolve(__dirname, './src'),
                    'comps': path.resolve(__dirname, './src/components'),
                    'utils': path.resolve(__dirname, './src/utils'),
                    'views': path.resolve(__dirname, './src/views'),
                    'apis': path.resolve(__dirname, './src/apis')
                },
                dedupe: [], // 强制将相同依赖解析为同一副本, ======待研究怎么用======
                //package.json 相关 开
                conditions: [], // 场景条件, ======待研究怎么用======
                mainFields: ['module', 'jsnext:main', 'jsnext'], // 入口点字段列表
                //package.json 相关 关
                extensions: ['.mjs', '.js', '.ts', '.jsx', '.tsx', '.json'], //导入时想要省略的扩展名列表
            },
            CSS: {
                // modules:'',
                // postcss: '',
                // preprocessorOptions: {},
            },
            JSON: {
                namedExports: true, // 是否支持从 .json 文件中进行按名导入
                stringify: false, // 若设置为 true,性能好,单不支持按名导入
            },
            esbuild: {}, // esbuild配置项,false为关闭esbuild
            assetsInclude: '', //指定其他静态文件
            logLevel: 'info', // 控制台输出级别,默认info,'info' | 'warn' | 'error' | 'silent'
            clearScreen: true, // 清屏, --clearScreen false
            envDir: './', //默认 root
            server: {
                host: '0.0.0.0',
                port: 9999, // 端口,若端口被占用时,自动尝试下一个端口
                strictPort: true, // 若端口被占用时直接退出
                https: false, // 启用 TLS + HTTP/2 配置,注意:当 server.proxy 选项 也被使用时,将会仅使用 TLS。false则关闭
                open: '/', // 项目启动时自动打开浏览器,可以设置默认打开的路径
                proxy: { // 服务器代理 https://github.com/http-party/node-http-proxy#options
                    '/foo': 'http://localhost:4567/foo',
                    '/apidd': {
                        target: loadEnv(mode, process.cwd()).VITE_APP_SERVER_URL,
                        changeOrigin: true,
                        rewrite: (path) => path.replace(/^\/api/, ''),
                        configure: (proxy, options) => {
                            // proxy 是 'http-proxy' 的实例
                        },
                    },
                    '^/fallback/.*': { // 正则
                        target: loadEnv(mode, process.cwd()).VITE_APP_SERVER_FALLBACK_URL,
                        changeOrigin: true,
                        rewrite: (path) => path.replace(/^\/fallback/, '')
                    },
                },
                cors: true, // 跨域,默认允许任何源 或 {origin: 'http://example.com',optionsSuccessStatus: 200}
                force: false, // 强制依赖预构建
                hmr: true, //禁用或配置 HMR 连接
                /**
                 * { 
                 *    protocol?: string, 
                 *    host?: string, 
                 *    port?: number, 
                 *    path?: string, 
                 *    timeout?: number, 
                 *    overlay?: boolean, // 屏蔽开发服务器错误提示
                 *    clientPort?: number, 
                 *    server?: Server 
                 * }
                 */
                watch: {}, //传递给 chokidar 的文件系统监听器选项 , ======待研究怎么用======
                // middlewareMode: 'html', // https://cn.vitejs.dev/guide/ssr.html#setting-up-the-dev-server  ======待研究怎么用======
                /**
                 * 以中间件模式创建 Vite 服务器。(不含 HTTP 服务器)
                 * 'ssr' 将禁用 Vite 自身的 HTML 服务逻辑,因此你应该手动为 index.html 提供服务。
                 * 'html' 将启用 Vite 自身的 HTML 服务逻辑。
                 */
            },
            build: { // 构建
                target: 'modules', // 构建目标格式,默认是modules,也可以是esbuild配置项,https://esbuild.github.io/api/#target
                outDir: 'dist', // 构建输出路径
                assetsDir: 'assets', //静态资源文件夹,和outDir同级
                assetsInlineLimit: 4096, // kb, 小于此值将内联base64格式
                cssCodeSplit: true, // 运行css文件按chunk拆分,chunk加载时插入,如果false则所有的样式导出为一个css文件
                sourcemap: false, // map文件
                /*
                 * true,将会创建一个独立的 source map 文件
                 * 'inline',source map 将作为一个 data URI 附加在输出文件中
                 * 'hidden' 的工作原理与 'true' 相似,只是 bundle 文件中相应的注释将不被保留。
                 */
                rollupOptions: {}, // rollup打包选项 https://rollupjs.org/guide/en/#big-list-of-options
                commonjsOptions: {}, // @rollup/plugin-commonjs 插件的选项
                dynamicImportVarsOptions: {}, // @rollup/plugin-dynamic-import-vars 的选项
                // lib: {}, // 构建为库,https://cn.vitejs.dev/guide/build.html#library-mode
                /**
                 * entry 是必须的因为库不能使用 HTML 作为入口。
                 * name 则是暴露的全局变量,在 formats 包含 'umd' 或 'iife' 时是必须的。
                 * 默认 formats 是 ['es', 'umd'] 。
                 * fileName 是输出的包文件名,默认 fileName 是 package.json 的 name 选项,同时,它还可以被定义为参数为 format 的函数。
                 */
                manifest: false, // 后端集成, ======待研究怎么用======
                minify: 'terser', // 最小化混淆,默认terser,可以是esbuild,或false关闭
                TerserOptions: {}, // terser混淆配置项
                cleanCssOptions: {}, // clean css 配置项, ======待研究怎么用======
                write: true, // 是否允许构建写入磁盘,false一般用在对构建做进一步处理
                emptyOutDir: true, // 构建前清库outDir目录
                brotliSize: true, //启用/禁用 brotli 压缩大小报告, 大型项目禁用可能提高构建速度
                chunkSizeWarningLimit: 500, //chunk 大小警告的限制(以 kbs 为单位
                watch: {}, // watchoptions,https://rollupjs.org/guide/en/#watch-options, 设置为 {} 则会启用 rollup 的监听器,代码改变时自动打包
            },
            optimizeDeps: { // 依赖优化
                // entries, '' | [], // 预构建入口
                // exclude: [], // 预构建排查的依赖
                // include: [], // 不在 node_modules 中的依赖包预构建
                // keepNames:false, //打包器有时需要重命名符号以避免冲突
            },
            ssr: { // 试验型,没做研究
                // external: [], //强制外部化的依赖
                // noExternal: '', // 防止外部化的依赖
                // target:'node', // SSR 服务器的构建目标
            }
        }
        if (command === 'serve') {
            // dev & serve

            //vite-plugin-mock
            let prodMock = true;
            const viteMockServeOptions = {
                mockPath: 'mock',
                supportTs: false,
                ignore: undefined,
                watchFiles: true,
                localEnabled: command === 'serve',
                prodEnabled: command !== 'serve' && prodMock,
                injectCode: ``, // prodEnabled=true生效 main.{ts,js}
                injectFile: '', // default: path.resolve(process.cwd(),'src/main.{ts,js}')
                configPath: '', //default: vite.mock.config.ts
                logger: true, //请求是输入日子
            }
            options.plugins.push(viteMockServe(viteMockServeOptions))
            console.log('mock')
        } else {
            // build
            options.plugins.push(viteCompression(viteCompressionOptions))
        }
        return options
    })
    // }


/**
 * jsdoc 方式智能提示
 * @type {import('vite').UserConfig}
 */
export const config = {
    server: {

    }
}

loadEnv 函数(使用.env文件)

import { loadEnv } from 'vite';

loadEnv('development', process.cwd());

检查process.cwd()路径下.env.development.local、.env.development、.env.local、.env这四个环境文件。
输出NODE_ENV和VITE_开头的键值对。
VITE_开头的键值对后面的不会覆盖前面的。
NODE_ENV的值后面的会覆盖前面的。


项目目录下创建.env.development .dev.production文件

NODE_ENV = 'development'
VITE_APP_BASE_API = '/api' // 暴露必须以VITE开头才能被Vite识别

项目使用

import.meta.env.XXXX
if (process.env.NODE_ENV === 'development') {
  BASE_URL = `${import.meta.env.VITE_APP_BASE_API}`
} else if (process.env.NODE_ENV === 'production') {
  BASE_URL = `${import.meta.env.VITE_APP_BASE_API}`
} else {
  BASE_URL = `${import.meta.env.VITE_APP_BASE_API}`
}

Vite.config 使用

import { defineConfig, loadEnv } from 'vite'
export default ({ mode }) => {
  return defineConfig({
    server: {
      proxy: {
            [`${loadEnv(mode, process.cwd()).VITE_APP_BASE_API}`]: {
                target: loadEnv(mode, process.cwd()).VITE_TEST_HOST, // 线上
                // rewrite: (path:any) => path.replace(/^\/api/, ''),
                changeOrigin: true,
                ws: true
            }
          }
    }
  })
}
import * as dotenv from "dotenv"
export interface ViteEnv {
    VITE_URL: string;
    VITE_BASE_URL: string;
    VITE_ZIP_NAME: string;
}

// 通过dotenv配置 需要加载指定.env文件 这样process.env打印到得就是对应得文件了 
// 这里的mode是我们启动时候的参数 npm run dev:prc 得到的mode就是prc
export function loadEnv(mode: string): ViteEnv {
    const ret: any = {};
    // 在使用之前我们先指定加载哪个环境变量 
    dotenv.config({
        path: `.env.${mode}` // .env.prc
    });
    
    for (const envName of Object.keys(process.env)) {
        let realName = (process.env as any)[envName].replace(/\\n/g, "\n");
        ret[envName] = realName;
        // 向process.env上扩展我们定义的VITE环境变量
        process.env[envName] = realName;
    }
    return ret
}
const regExps = (value: string, reg: string): string => {
    return value.replace(new RegExp(reg, "g"), "");
};

//   根据环境变量返回指定得proxy
export function createProxy(targetProxyUrl:string,baseUrl:string) {
    return {
        [`${baseUrl}`]: {
            target: targetProxyUrl,
            changeOrigin: true,
            rewrite: (path: string) => regExps(path,`${baseUrl}`)
        },
    }
}
# mode是在这里拿到的
export default ({ command, mode }) => {}

import { loadEnv, createProxy } from "./src/utils/load-env"

const { VITE_URL, VITE_BASE_URL, VITE_ZIP_NAME } = loadEnv(mode)
# proxy部分
 serve: {
      port: 8999,
      proxy: createProxy(VITE_URL, VITE_BASE_URL)
 }

在其他地方使用 request.ts

request.ts中我们可以通过 import.meta.env 拿到我们在环境变量文件中的定义的Vite变量

这样在配置axios的时候。

const baseURL = (import.meta.env.VITE_BASE_URL as string)
const service: AxiosInstance = axios.create({
  baseURL,
  timeout: 30 * 1000,
});

viteBuild.ts 文件

//位置 @/utils/viteBuild.ts

import dotenv from 'dotenv';

// 定义接口类型声明
export interface ViteEnv {
  VITE_PORT: number;
  VITE_OPEN: boolean;
  VITE_PUBLIC_PATH: string;
}

/**
 * vite 打包相关
 * @link 参考:https://cn.vitejs.dev/guide/env-and-mode.html
 * @returns 返回 `VITE_xxx` 环境变量和模式信息
 */
export function loadEnv(): ViteEnv {
  const env = process.env.NODE_ENV;
  const ret: any = {};
  const envList = [`.env.${env}.local`, `.env.${env}`, '.env.local', '.env'];
  envList.forEach((e) => {
    dotenv.config({ path: e });
  });
  for (const envName of Object.keys(process.env)) {
    let realName = (process.env as any)[envName].replace(/\\n/g, '\n');
    realName = realName === 'true' ? true : realName === 'false' ? false : realName;
    if (envName === 'VITE_PORT') realName = Number(realName);
    if (envName === 'VITE_OPEN') realName = Boolean(realName);
    ret[envName] = realName;
    process.env[envName] = realName;
  }
  return ret;
}

使用

import { loadEnv } from './src/utils/viteBuild';

const { VITE_PORT, VITE_OPEN, VITE_PUBLIC_PATH } = loadEnv();

process.cwd()


process.cwd()方法是流程模块的内置应用程序编程接口,用于获取node.js流程的当前工作目录。


vite中引入预处理全局scss文件(全局样式)

cssPreprocessOptions: {
    scss: {
      additionalData: '@import "./src/assets/scss/all.scss";' // 添加公共样式
    }
  }


vite+typescript从入门到实战(三):https://developer.aliyun.com/article/1483578

相关文章
|
2月前
|
JavaScript 前端开发
【TypeScript入门】TypeScript入门篇——数据类型
我们人类可以很容易的分清数字与字符的区别,但是计算机并不能呀,计算机虽然很强大,但从某种角度上看又很傻,除非你明确的告诉它,1是数字,“汉”是文字,否则它是分不清1和‘汉’的区别的,因此,在每个编程语言里都会有一个叫数据类型的东东,其实就是对常用的各种数据类型进行了明确的划分,你想让计算机进行数值运算,你就传数字给它,你想让他处理文字,就传字符串类型给他。
17 3
|
14天前
|
JavaScript
vite+typescript从入门到实战(三)
vite+typescript从入门到实战
31 0
|
14天前
|
JavaScript 前端开发
vite+typescript从入门到实战(一)
vite+typescript从入门到实战
64 0
|
21天前
|
JavaScript 前端开发
TypeScript极速入门笔记1
TypeScript极速入门笔记1
30 4
|
3月前
|
存储 JavaScript 前端开发
【HarmonyOS 4.0 应用开发实战】TypeScript入门之元组详讲
【HarmonyOS 4.0 应用开发实战】TypeScript入门之元组详讲
43 0
|
3月前
|
JavaScript 前端开发
【HarmonyOS 4.0 应用开发实战】TypeScript入门之模块化详讲
【HarmonyOS 4.0 应用开发实战】TypeScript入门之模块化详讲
33 0
|
3月前
|
JavaScript 前端开发 索引
【HarmonyOS 4.0 应用开发实战】TypeScript入门之接口详讲
【HarmonyOS 4.0 应用开发实战】TypeScript入门之接口详讲
40 0
|
3月前
|
JavaScript
【HarmonyOS 4.0 应用开发实战】TypeScript入门之声明、数据类型、函数、类的详讲
【HarmonyOS 4.0 应用开发实战】TypeScript入门之声明、数据类型、函数、类的详讲
44 0
|
3月前
|
JavaScript 前端开发 安全
Apollo与TypeScript:强大类型检查在前端开发中的应用
Apollo与TypeScript:强大类型检查在前端开发中的应用
|
8天前
|
JavaScript 前端开发 编译器
TypeScript中的高级类型:联合类型、交叉类型与条件类型深入解析
【4月更文挑战第23天】探索TypeScript的高级类型。这些特性增强类型系统的灵活性,提升代码质量和维护性。