Skip to content

Commit

Permalink
feat: 插件vite-plugin-meta-env功能完成
Browse files Browse the repository at this point in the history
  • Loading branch information
wforguo committed Jul 14, 2023
1 parent 6215534 commit fae9fb8
Show file tree
Hide file tree
Showing 13 changed files with 370 additions and 40 deletions.
5 changes: 4 additions & 1 deletion index.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
export function setupCounter(element: HTMLButtonElement): void
import type { Plugin } from 'vite'
import { EnvVars } from './lib/main'

export function VitePluginMetaEnv(vars: EnvVars): Plugin
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<link rel="icon" type="image/svg+xml" href="/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>vite-plugin-meta-env</title>
</head>
Expand Down
143 changes: 143 additions & 0 deletions init.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
# vite + ts + eslint + prettier

## vite

```bash
pnpm create vite
```

## eslint + prettier

这里只做 vite + ts + eslint + prettier 的配置

### eslint

#### 安装

```bash
pnpm add eslint -D
```

#### 配置

```bash
pnpm eslint --init
```

如下:
```
You can also run this command directly using 'npm init @eslint/config'.
npx: installed 41 in 3.421s
✔ How would you like to use ESLint? · problems
✔ What type of modules does your project use? · esm
✔ Which framework does your project use? · none
✔ Does your project use TypeScript? · No / Yes
✔ Where does your code run? · browser
✔ What format do you want your config file to be in? · JavaScript
The config that you've selected requires the following dependencies:
@typescript-eslint/eslint-plugin@latest @typescript-eslint/parser@latest
✔ Would you like to install them now? · No / Yes
✔ Which package manager do you want to use? · pnpm
Installing @typescript-eslint/eslint-plugin@latest, @typescript-eslint/parser@latest
Packages: +32
++++++++++++++++++++++++++++++++
Progress: resolved 168, reused 138, downloaded 0, added 0, done
devDependencies:
+ @typescript-eslint/eslint-plugin 6.0.0
+ @typescript-eslint/parser 6.0.0
Successfully created .eslintrc.cjs file in /Users/forguo/work/wei/projects/vite-plugin-meta-env
```

-`.eslintrc.cjs` 中 env 添加如下配置:

```js
{
// ++
node: true
}
```

-`package.json` 中添加如下配置:

// eslint . 为指定lint当前项目中的文件
// --ext 为指定lint哪些后缀的文件
// --fix 开启自动修复

```json
{
"scripts": {
"lint": "eslint . --ext .js,.ts --fix --ignore-path .gitignore"
}
}
```

### prettier

#### 安装

```bash

pnpm add prettier -D
```

#### 配置

- 在根目录下新建 `.prettierrc.cjs` 文件,添加如下配置:

```js
module.exports = {
$schema: 'https://json.schemastore.org/prettierrc',
printWidth: 120, // 单行输出(不折行)的(最大)长度
semi: false, // 结尾使用分号, 默认true
useTabs: false, // 使用tab缩进,默认false
tabWidth: 4, // tab缩进大小,默认为2
singleQuote: true, // 使用单引号, 默认false(在jsx中配置无效, 默认都是双引号)
jsxSingleQuote: true, // jsx 不使用单引号,而使用双引号
trailingComma: 'none', // 行尾逗号,默认none,可选 none|es5|all es5 包括es5中的数组、对象,all 包括函数对象等所有可选
bracketSpacing: true, // 对象中的空格 默认true,true: { foo: bar },false: {foo: bar}
htmlWhitespaceSensitivity: 'ignore', // 指定 HTML 文件的全局空白区域敏感度, "ignore" - 空格被认为是不敏感的
jsxBracketSameLine: false,
arrowParens: 'avoid', // 箭头函数参数括号 默认avoid 可选 avoid| always, avoid 能省略括号的时候就省略 例如x => x,always 总是有括号
proseWrap: 'always' // 当超出print width(上面有这个参数)时就折行
}
```

-`package.json` 中添加如下配置:

```json
{
"scripts": {
"format": "prettier --write ."
}
}
```

### 解决eslint与prettier的冲突

> eslint负责我们的代码质量,prettier负责我们的代码格式。但是会存在eslint有部分规则与prettier冲突了,保存的时候显示运行了eslint的修复命令,然后再运行prettier格式化,所以就会出现屏幕闪一下然后又恢复到报错的现象。
查阅资料会发现,社区已经为我们提供了一个非常成熟的方案,即eslint-config-prettier + eslint-plugin-prettier。

- eslint-plugin-prettier: 基于 prettier 代码风格的 eslint 规则,即eslint使用pretter规则来格式化代码。

- eslint-config-prettier: 禁用所有与格式相关的 eslint 规则,解决 prettier 与 eslint 规则冲突,确保将其放在 extends 队列最后,这样它将覆盖其他配置

#### 安装

```bash
pnpm add eslint-plugin-prettier eslint-config-prettier -D
```

#### 配置

-`.eslintrc.cjs``extends` 添加如下配置:

```js
[
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
// +++,需在最后
'plugin:prettier/recommended'
]
```
59 changes: 51 additions & 8 deletions lib/main.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,52 @@
export function setupCounter(element: HTMLButtonElement) {
let counter = 0
const setCounter = (count: number) => {
counter = count
element.innerHTML = `count is ${counter}`
}
element.addEventListener('click', () => setCounter(++counter))
setCounter(0)
/**
* @Author: forguo
* @Date: 2023/7/15 10:24
* @Description: index.ts
*/

import type { Plugin, UserConfig } from 'vite'

export interface EnvVars {
[key: string]: string | null | undefined
}

/**
* 生成 import.meta.env 环境变量
* @param {EnvVars} vars
*/
function defineEnvVars(vars: EnvVars) {
if (!vars) {
throw new Error('vite-plugin-meta-env: configuration is required.')
}
if (toString.call(vars) !== '[object Object]') {
throw new Error('vite-plugin-meta-env: configuration must be an object.')
}
if (Object.keys(vars).length === 0) {
throw new Error('vite-plugin-meta-env: configuration can not be empty.')
}
const metaEnv: Record<string, string | null> = {}
for (const key in vars) {
metaEnv[`import.meta.env.${key}`] = JSON.stringify(vars[key])
}
return metaEnv
}

/**
* 使用 define 选项,暴露一个不含前缀的变量
* https://cn.vitejs.dev/config/shared-options.html#define
* @param {EnvVars} vars
*/
export default function VitePluginMetaEnv(vars: EnvVars): Plugin {
return {
name: 'vite-plugin-meta-env',
/**
* // https://cn.vitejs.dev/guide/api-plugin.html#vite-specific-hooks
* @param {UserConfig} config 原始用户配置
* @param {ConfigEnv} env 配置环境的变量:包含正在使用的 mode 和 command
*/
config(): UserConfig {
// 返回一个将被深度合并到现有配置中的部分配置对象,或者直接改变配置
return { define: defineEnvVars(vars) }
}
}
}
43 changes: 35 additions & 8 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,19 +1,43 @@
{
"name": "vite-plugin-meta-env",
"private": true,
"private": false,
"version": "0.0.0",
"type": "module",
"author": "wforguo@qq.com",
"description": "a vite plugin, define dynamic env variables in import.meta.env",
"license": "ISC",
"keywords": [
"vite-plugin-meta-env",
"dynamic env variables",
"import.meta.env",
"vite define",
"vite plugin",
"vite",
"vite",
"vue3",
"plugin",
"env",
"forguo",
"a vite plugin, define dynamic env variables in import.meta.env",
"用于在 vite 项目中暴露动态的或者不含前缀的环境变量"
],
"homepage": "https://github.com/wei-design/vite-plugin-meta-env",
"repository": {
"type": "git",
"url": "https://github.com/wei-design/vite-plugin-meta-env"
},
"files": [
"dist",
"index.d.ts"
"index.d.ts",
"readme.md"
],
"main": "./dist/counter.umd.cjs",
"module": "./dist/counter.js",
"type": "module",
"main": "./dist/meta-env.umd.cjs",
"module": "./dist/meta-env.js",
"types": "./index.d.ts",
"exports": {
"types": "./index.d.ts",
"import": "./dist/counter.js",
"require": "./dist/counter.umd.cjs"
"import": "./dist/meta-env.js",
"require": "./dist/meta-env.umd.cjs"
},
"scripts": {
"commit": "cz",
Expand All @@ -37,9 +61,12 @@
"typescript": "^5.1.3",
"vite": "^4.3.9"
},
"engines": {
"node": ">=16.0.0"
},
"lint-staged": {
"*.{js,jsx,ts,tsx,vue}": [
"eslint --fix",
"npm run lint",
"git add ."
]
},
Expand Down
Binary file added public/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion public/vite.svg

This file was deleted.

94 changes: 94 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# vite-plugin-meta-env

[![commitizen](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli)
[![Wei Design](https://img.shields.io/npm/v/vite-plugin-meta-env.svg?style=flat-square)](https://www.npmjs.org/package/vite-plugin-meta-env)

define dynamic env variables in import.meta.env

## 一、介绍

该插件:用于在 [vite](https://cn.vitejs.dev/) 项目中暴露**动态的**或者**不含前缀**的环境变量

### 使用场景

- 1、**动态**的环境变量

- 2、**不含前缀**的环境变量

---

`vite` 项目当中,通常会暴露 [envPrefix](https://cn.vitejs.dev/config/shared-options.html#envprefix) 【默认为 `VITE_`】开头的环境变量,

如:`VITE_API_URL``VITE_APP_NAME` 等等。

有时候则需要使用到一些**动态的环境变量**,以及**不含前缀的变量**如:`APP_VERSION``APP_BUILD_TIME` 等等。

本插件就是为了解决这个问题而生的。

这里使用了 `vite` 独有钩子:[config](https://cn.vitejs.dev/guide/api-plugin.html#config) 以及 [define](https://cn.vitejs.dev/config/shared-options.html#define) 配置选项来完成该功能

## 二、使用

- 安装

```bash
pnpm i -D vite-plugin-meta-env
```

- 配置

`VitePluginMetaEnv` 接收一个对象作为参数,对象的 key 为变量名,value 为变量值。

```ts
// vite.config.js

import { defineConfig } from 'vite'

// 引入插件
import VitePluginMetaEnv from 'vite-plugin-meta-env'

export default () => {
// 环境变量,对象结构
const metaEnv = {
APP_VERSION: '1.0.0'
}
return defineConfig({
// ...
plugins: [
// 添加插件
VitePluginMetaEnv(metaEnv)
]
})
}
```

在项目当中就可以通过 `import.meta.env.APP_VERSION` 来访问我们定义的环境变量了

[demo](https://github.com/wforguo/vue3-quick-start/blob/master/vitest.config.ts)

[预览](https://wforguo.github.io/vue3-quick-start/)

## 三、注意项

[TypeScript 的智能提示](https://cn.vitejs.dev/guide/env-and-mode.html#intellisense)

对于使用 TypeScript 的开发者来说,请确保在 env.d.ts 或 vite-env.d.ts 文件中添加类型声明,以获得类型检查以及代码提示。

```ts
// env.d.ts
/// <reference types="vite/client" />
interface ImportMetaEnv {
readonly BASE_URL: string // 内建变量
readonly MODE: string // 内建变量
readonly APP_VERSION: string
// 更多环境变量...
}

interface ImportMeta {
readonly env: ImportMetaEnv
}
```

---

[author](https://github.com/wforguo)
Loading

0 comments on commit fae9fb8

Please sign in to comment.