最新要闻

广告

手机

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

iphone11大小尺寸是多少?苹果iPhone11和iPhone13的区别是什么?

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

警方通报辅警执法直播中被撞飞:犯罪嫌疑人已投案

家电

全球最资讯丨@vue/cli 插件开发之自动根据目录列表生成别名配置

来源:博客园


(资料图片)

1.相关文档

  1. @vue/cli官方文档 @vue/cli
  2. @vue/cli插件开发指南 @vue/cli

2.插件命名规范

为了让一个 CLI 插件在 Vue CLI 项目中被正常使用,它必须遵循 vue-cli-plugin-或者 @scope/vue-cli-plugin-这样的命名惯例。这样你的插件才能够:

  • 被 @vue/cli-service 发现;
  • 被其他开发者通过搜索发现;
  • 通过 vue add 或者 vue invoke 安装。

命名示例:vue-cli-plugin-auto-alias or @jiangwy/vue-cli-plugin-auto-alias

3. 插件市场

https://www.npmjs.com/search?q=vue-cli-plugin搜索以vue-cli-plugin作为关键字的插件名称,则会展示vue-cli-plugin相关插件

4.示例

此示例插件名称为vue-cli-plugin-inject-alias相关仓库:vue-cli-plugin-inject-alias

  1. 初始化仓库使用pnpm init初始化目录
  2. 安装相关依赖
  • 代码规范插件
pnpm add eslint @jiangwy/eslint-config -D
  • ts相关插件
pnpm add typescript @types/node -D
  • 打包相关插件
pnpm add rollup rollup-plugin-typescript2 bumpp -D
  • 插件依赖包
pnpm add @vue/cli-service  -D
  1. 完善package.json
{    "name": "vue-cli-plugin-inject-alias",    "version": "0.0.4",    "description": "automatically generate alias based on path",    "author": "jiangweiye  (https://github.com/jwyGithub)",    "license": "MIT",    "homepage": "https://github.com/jwyGithub/vue-cli-plugin-inject-alias",    "keywords": [        "vue",        "vue-cli",        "vue-cli-plugin",        "vue-cli-plugin-alias",        "alias"    ],    "exports": {        ".": {            "require": "./dist/index.cjs.js"        }    },    "main": "./dist/index.cjs.js",    "types": "./dist/index.d.ts",    "files": [        "dist"    ],    "scripts": {        "build": "rollup -c",        "release": "npm run build && bumpp package.json --commit --push --tag && npm publish --access=public",        "lint": "eslint ."    },    "peerDependencies": {        "@vue/cli-service": "*"    },    "devDependencies": {        "@jiangweiye/eslint-config": "^0.0.21",        "@types/node": "^18.11.18",        "@vue/cli-service": "~5.0.0",        "bumpp": "^8.2.1",        "eslint": "^8.31.0",        "rollup": "^3.9.1",        "rollup-plugin-typescript2": "^0.34.1",        "typescript": "^4.9.4"    }}
  1. 初始话tsconfig.json
{    "compilerOptions": {        "target": "esnext",        "useDefineForClassFields": true,        "lib": ["ESNext", "DOM"],        "moduleResolution": "Node",        "strict": true,        "module": "esnext"    },    "include": ["src/**/*"],    "exclude": ["node_modules", "**/*.spec.ts"]}
  1. 增加打包配置文件
// rollup.config.jsconst { defineConfig } = require("rollup");const ts = require("rollup-plugin-typescript2");module.exports = defineConfig({    input: "./src/index.ts",    output: [        {            format: "cjs",            exports: "default",            file: "dist/index.cjs.js"        }    ],    plugins: [        ts({            tsconfig: "./tsconfig.json",            tsconfigOverride: {                compilerOptions: {                    declaration: true,                    declarationMap: false,                    declarationDir: "dist",                    allowJs: true                },                include: ["src/**/*"]            },            clean: true,            useTsconfigDeclarationDir: true        })    ],    external: ["@vue/cli-service", "path", "fs"]});
  1. 插件核心代码逻辑@vue/cli官方提供了插件api注入入口,导出函数,在项目启动的时候,脚手架会在当前项目中查找相关插件,并执行入口函数
function alias(api: PluginAPI) {    // your plugin code}

插件实现思路,首先获得执行项目的根路径,可以使用官方提供的apiapi.getCwd()获得,其次使用fs模块提供的readdirSync方法获取src目录下的所有文件夹

/** * @description 获取所有文件夹 * @param path * @returns */export const getDirs = (path: string): GetDirs => {    try {        const dirs = readdirSync(path);        return dirs.reduce((result, name) => {            const fullPath = join(path, name);            isDir(fullPath) && result.push({ dirName: name, dirPath: fullPath });            return result;        }, []);    } catch (error: any) {        throw new Error(error);    }};

通过fs模块提供的lstatSync(path).isDirectory();判断是否是文件夹

/** * @description 是否是文件夹 * @param path * @returns */export const isDir = (path: string): boolean => {    return lstatSync(path).isDirectory();};

得到最终所有的文件夹后,生成alias对象

function genAlias(root: string) {    const dirs = getDirs(root);    return dirs.reduce<{ [key: string]: string }>((result, item) => {        const key = `@${item.dirName}`;        const value = item.dirPath;        result[key] = value;        return result;    }, {});}

最后通过使用api.configureWebpack方法将生成的alias对象注入最终的项目配置中

function alias(api: PluginAPI) {    const cwd = api.getCwd();    const root = join(cwd, "src");    if (!hasFile(root)) {        return;    }    api.configureWebpack(config => {        let baseAlias = {};        if (config.resolve && config.resolve.alias) {            baseAlias = config.resolve.alias;        }        return {            resolve: {                alias: { ...genAlias(root), ...baseAlias }            }        };    });}

关键词: 目录列表 项目启动