English | 简体中文
Important
如果你喜欢这个项目,希望你能给这个仓库点一个 star ⭐,你的支持能帮助这个项目加入到 unplugin 组织!
npm i unplugin-preprocessor-directives
Vite
// vite.config.ts
import PreprocessorDirectives from 'unplugin-preprocessor-directives/vite'
export default defineConfig({
plugins: [
PreprocessorDirectives({ /* options */ }),
],
})
Example: playground/
Rollup
// rollup.config.js
import PreprocessorDirectives from 'unplugin-preprocessor-directives/rollup'
export default {
plugins: [
PreprocessorDirectives({ /* options */ }),
],
}
Webpack
// webpack.config.js
module.exports = {
/* ... */
plugins: [
require('unplugin-preprocessor-directives/webpack')({ /* options */ })
]
}
Nuxt
// nuxt.config.js
export default defineNuxtConfig({
modules: [
['unplugin-preprocessor-directives/nuxt', { /* options */ }],
],
})
This module works for both Nuxt 2 and Nuxt Vite
Vue CLI
// vue.config.js
module.exports = {
configureWebpack: {
plugins: [
require('unplugin-preprocessor-directives/webpack')({ /* options */ }),
],
},
}
esbuild
// esbuild.config.js
import { build } from 'esbuild'
import PreprocessorDirectives from 'unplugin-preprocessor-directives/esbuild'
build({
plugins: [PreprocessorDirectives()],
})
Rspack (⚠️ 实验性)
// rspack.config.js
module.exports = {
plugins: [
require('unplugin-preprocessor-directives/rspack')({ /* options */ }),
],
}
您可以使用以下两个预处理器指令来定义或取消定义 symbols,以便进行条件编译:
#define
: 定义一个 symbol.#undef
: 取消定义一个 symbol.
使用 #define
可以定义一个 symbol。将 symbol 作为表达式传递给 #if
指令时,表达式的值将为 true
,如下例所示:
// #define VERBOSE
// #if VERBOSE
console.log('Verbose output version')
// #endif
#if
: 打开条件编译,只有当指定的 symbol 被定义并求值为 true 时,代码才会被编译。#elif
:关闭前面的条件编译,并判断是否定义了指定的 symbol 并求值为 true 时,打开一个新的条件编译。#else
: 如果前一个指定的 symbol 未定义或求值为 false,则关闭前一个条件编译,并打开一个新的条件编译。#endif
: 关闭前面的条件编译。
Note
默认情况下,使用 vite 的 loadEnv
函数根据process.env.NODE_ENV
加载环境变量并作为条件编译 symbols。
// src/index.ts
// #if DEV
console.log('Debug version')
// #endif
// #if !MYTEST
console.log('MYTEST is not defined or false')
// #endif
可以使用运算符 ==
(相等)和 !=
(不等)来测试 true
或 false
。true
表示 symbol 已定义。语句 #if DEBUG
与 #if (DEBUG == true)
意义相同。支持使用 &&
(与)、||
(或) 和 !
(非) 操作符来判断是否定义了多个 symbols。还可以用括号将 symbols 和运算符分组。
class MyClass {
constructor() {
// #if (DEBUG && MYTEST)
console.log('DEBUG and MYTEST are defined')
// #elif (DEBUG==false && !MYTEST)
console.log('DEBUG and MYTEST are not defined')
// #endif
}
}
可以指示编译器生成用户定义的编译器错误、警告和信息。
#error
: 生成一条错误消息。#warning
: 生成一条警告消息。#info
: 生成一条信息消息。
// #error this is an error message
// #warning this is a warning message
// #info this is an info message
您可以使用 defineDirective
定义自己的指令。
以内置指令为例:
export const MessageDirective = defineDirective<MessageToken, MessageStatement>(context => ({
lex(comment) {
return simpleMatchToken(comment, /#(error|warning|info)\s*(.*)/)
},
parse(token) {
if (token.type === 'error' || token.type === 'warning' || token.type === 'info') {
this.current++
return {
type: 'MessageStatement',
kind: token.type,
value: token.value,
}
}
},
transform(node) {
if (node.type === 'MessageStatement') {
switch (node.kind) {
case 'error':
context.logger.error(node.value, { timestamp: true })
break
case 'warning':
context.logger.warn(node.value, { timestamp: true })
break
case 'info':
context.logger.info(node.value, { timestamp: true })
break
}
return createProgramNode()
}
},
generate(node, comment) {
if (node.type === 'MessageStatement' && comment)
return `${comment.start} #${node.kind} ${node.value} ${comment.end}`
},
}))
指令的执行优先级
pre
尽可能早执行post
尽可能晚执行