Vue3+Ts打包依赖库记录

前言

vue-cli 自带的是 webpack 的打包方式,打出的包体积有点大,而 vite 自带的是 rollup 的打包方式,这种方式打包的体积就非常小,官网也有一些使用说明,所以学会之后还是比较很方便的。

依赖

依赖名称 依赖版本 依赖说明
vite ^2.9.9 vue快速构建工具
@vitejs/plugin-vue ^2.3.3 vite支持打包vue插件
@vitejs/plugin-vue-jsx ^1.3.10 vite支持打包vue-jsx语法插件
autoprefixer ^10.4.7 自动给css加上各浏览器前缀
vite-plugin-dts ^1.2.0 打包类型声明文件
postcss-flexbugs-fixes ^5.0.2 修复浏览器flex的一些bug

详细配置

// vite.config.js
import {
    
    defineConfig} from 'vite';
import vue from '@vitejs/plugin-vue';
import vueJsx from '@vitejs/plugin-vue-jsx';
import autoprefixer from 'autoprefixer';
import pff from 'postcss-flexbugs-fixes';
import dts from 'vite-plugin-dts';

import path from 'path';
import {
    
    name} from './package.json';

export default defineConfig({
    
    
    css: {
    
    
        postcss: {
    
    
            plugins: [autoprefixer({
    
    
                overrideBrowserslist: [
                    "defaults",
                    "not ie < 8",
                    "last 2 versions",
                    "> 1%",
                    "iOS 7",
                    "last 3 iOS versions"
                ],
                grid: true,
            }), pff]
        }
    },
    plugins: [vue(), vueJsx(), dts()],
    resolve: {
    
    
        alias: {
    
    
            '@': '/src'
        },
    },
    build: {
    
    
        minify: "terser",
        brotliSize: true,
        sourcemap: false,
        terserOptions: {
    
    
            compress: {
    
    
                drop_console: true,
                drop_debugger: true
            },
            keep_classnames: true,
        },
        lib: {
    
    
            entry: path.resolve(__dirname, 'src/index.ts'),
            name,
            formats: ['es', 'cjs', 'umd'],
            fileName: (format) => `${
      
      name}.${
      
      format}.js`
        },
        // assetsDir: 'assets',
        outDir: 'dist',
        rollupOptions: {
    
    
            external: [
                'vue',
                'vuex',
                'vue-router',
                'axios',
                'moment',
                'mitt',
                'js-cookie',
                'crypto-js/aes',
                'crypto-js/enc-utf8',
                'crypto-js/pad-pkcs7',
                'crypto-js/mode-ecb',
                'crypto-js/md5',
                'crypto-js/enc-utf8',
                'crypto-js/enc-base64',
                'ant-design-vue',
                '@ant-design/icons-vue',
                'lodash-es'
            ],
            output: {
    
    
                globals: {
    
    
                    "moment": "moment",
                    "vue": "vue",
                    "vue-router": "vueRouter",
                    "vuex": "vuex",
                    "js-cookie": "cookies",
                    "crypto-js/aes": "aes",
                    "crypto-js/enc-utf8": "UTF8",
                    "crypto-js/pad-pkcs7": "pkcs7",
                    "crypto-js/mode-ecb": "ECB",
                    "crypto-js/md5": "md5",
                    "crypto-js/enc-base64": "Base64",
                    "axios": "axios",
                    "ant-design-vue": "antDesignVue",
                    "mitt": "mitt",
                    "@ant-design/icons-vue": "$Icon",
                    "lodash-es": "lodashEs"
                }
            }
        }
    }
});

发布脚本

const fs = require('fs');
const pro = require('child_process');

class Publish {
    
    
    constructor(config) {
    
    
        this._config = {
    
    
            pkg: 'package.json',
            version: '',
            versionRule: /^([1-9]\d|[1-9])(.([1-9]\d|\d)){2}$/,
            versionAuto: {
    
    
                step: 1,
                main: false,
                secondary: false,
                revise: true
            },
            cpList: ['package.json', 'README.md'],
            dir: 'dist',
            command: {
    
    
                build: 'npm run build:vite',
                publish: 'npm publish'
            },
            package: {
    
    }
        };
        Object.assign(this._config, config);
        this._pkg = JSON.parse(fs.readFileSync(this._config.pkg).toString());
        Object.assign(this._pkg, this._config.package);
        if (this._config.version) {
    
    
            this._assert(!this._checkVersion(this._config.version), "config中version属性不符合规范");
        } else {
    
    
            this._assert(!this._checkVersion(this._pkg.version), "package.json中version属性不符合规范");
        }
    }

    /**
     * 版本号转换
     * @param {string|{r: number, s: number, m: number}} version 版本号
     * @returns {string|{r: number, s: number, m: number}}
     */
    _transform(version) {
    
    
        if (typeof version === 'string') {
    
    
            const [m, s, r] = version.split('.');
            return {
    
    
                m: parseInt(m), s: parseInt(s), r: parseInt(r)
            };
        } else {
    
    
            const {
    
    m, s, r} = version;
            return `${
      
      m}.${
      
      s}.${
      
      r}`;
        }
    }

    /**
     * 验证版本号是否符合规范
     * @param {string} version 版本号
     * @returns {boolean}
     */
    _checkVersion(version) {
    
    
        return this._config.versionRule.test(version);
    }

    /**
     * 断言
     * @param {boolean} b
     * @param {string} m
     */
    _assert(b, m) {
    
    
        if (b) {
    
    
            throw Error(m);
        }
    }

    /**
     * 迭代版本
     */
    _version() {
    
    
        function versionSwap(newVersion) {
    
    
            this._pkg.oldVersion = this._pkg.version;
            this._pkg.version = newVersion;
            fs.writeFileSync(this._config.pkg, JSON.stringify(this._pkg));
            console.log(`+ 迭代版本 -> ${
      
      this._pkg.version}`);
            console.log(`+ 历史版本 -> ${
      
      this._pkg.oldVersion}`);
        }
        if (this._config.version) {
    
    
            versionSwap.call(this, this._config.version);
            console.log(`+ 设置版本 -> ${
      
      this._config.version}`);
        } else {
    
    
            const {
    
    m, s, r} = this._transform(this._pkg.version);
            const {
    
    main, secondary, revise, step} = this._config.versionAuto;
            versionSwap.call(this, this._transform({
    
    
                m: main ? m + step : m,
                s: secondary ? s + step : s,
                r: revise ? r + step : r
            }));
        }
    }

    /**
     * 移动文件到指定目录
     */
    _copyFiles() {
    
    
        const {
    
    cpList, dir} = this._config;
        if (!fs.existsSync(dir)) {
    
    
            fs.mkdirSync(dir);
        }
        cpList.forEach(src => {
    
    
            fs.copyFileSync(src, `${
      
      dir}/${
      
      src}`);
            console.log(`+ 文件拷贝 - ${
      
      src} -> ${
      
      dir}/${
      
      src}`);
        });
    }

    /**
     * 执行...
     */
    exec() {
    
    
        const {
    
    dir, command} = this._config;
        let result;

        console.log(`--------------------[依赖包清除开始]--------------------`);
        result = pro.execSync(`npm rm -rf ${
      
      dir}`);
        console.log(result.toString());

        console.log(`--------------------[依赖包构建开始]--------------------`);
        result = pro.execSync(`${
      
      command.build}`);
        console.log(result.toString());

        console.log(`---------------------[版本迭代开始]---------------------`);
        this._version();

        console.log(`---------------------[文件拷贝开始]---------------------`);
        this._copyFiles();

        console.log(`--------------------[依赖包发布开始]--------------------`);
        result = pro.execSync(`cd ${
      
      dir} && ${
      
      command.publish}`);
        console.log(result.toString());
    }

    static run(config) {
    
    
        try {
    
    
            console.log(`=================[一键发布脚本执行开始]=================`);
            new Publish(config).exec();
            console.log(`=================[一键发布脚本执行结束]=================`);
        } catch (e) {
    
    
            console.error(e);
        }
    }
}

Publish.run();

构建命令

{
    
    
    "scripts":{
    
    
        "build:vite": "npm rm -rf dist && vite build --config vite.config.js",
        "build:publish": "cls && node publish.js"
    },
	"main": "cmt-vue-lib.cjs.js",
	"module": "cmt-vue-lib.es.js",
	"browser": "cmt-vue-lib.umd.js",
	"typings": "index.d.js",
    "peerDependencies": {
    
    
        "@ant-design/icons-vue": "^6.1.0",
        "ant-design-vue": "^3.2.5",
        "axios": "^0.26.1",
        "crypto-js": "^4.1.1",
        "js-cookie": "^3.0.1",
        "lodash-es": "^4.17.21",
        "mitt": "^3.0.0",
        "moment": "^2.29.3",
        "vue": "^3.2.13",
        "vue-router": "^4.0.3",
        "vuex": "^4.0.0"
  	}
}

常见问题

  • 在标签上使用资源路径,打包后资源不存在的问题。需要以import的形式导入资源。

  • 导入图片相关资源报错问题。需要增加声明文件images.d.ts

    // images.d.ts
    declare module '*.svg';
    declare module '*.png';
    declare module '*.jpg';
    declare module '*.jpeg';
    declare module '*.gif';
    declare module '*.bmp';
    declare module '*.tiff';
    
  • 用vite打包成lib库图片资源不会分离出来,它将会以base64编码形式存放在css中。

组件库类型

定义类型

// 组件库类型
export interface XUIComponents {
    
    
    XLayout: typeof Layout;
    XLayoutContent: typeof LayoutContent;
    XLayoutSlider: typeof LayoutSlider
    XCard: typeof Card;
    XCardBody: typeof CardBody;
    XCardFooter: typeof CardFooter;
    XCardHeader: typeof CardHeader;
    XCardTitle: typeof CardTitle;
    XModal: typeof Modal;
    XEllipsis: typeof Ellipsis;
    XEmpty: typeof Empty;
    XIcon: typeof Icon;
    XIconSelector: typeof IconSelector;
}

// vue3 globalConfig
export interface XUIProperties {
    
    
    $xSoft: ICmSoft;
    $xSysSvr: SystemStoreService;
    $xUserSvr: UserStoreService;
    $xMsgSvr: MessageApi;
    $xModalSvr: typeof AntdModal;
    $xRequest: VAxios;
    $xWebCache: WebStorage;
    $xConfig: ISoftConfig;
}

// vue3 options扩展
export interface XUIOptions {
    
    
    title?: string;
    single?: boolean;
}

安装类型

declare module 'vue' {
    
    
    interface GlobalComponents extends CmUIComponents {
    
    
    }
}

declare module '@vue/runtime-core' {
    
    
    interface ComponentCustomProperties extends CmUIProperties {
    
    
    }
    
    interface ComponentCustomOptions extends CmUIOptions{
    
    
    }
}

猜你喜欢

转载自blog.csdn.net/qq_34191778/article/details/126166924