initial commit
commit
1ed54ce481
@ -0,0 +1 @@
|
||||
node_modules
|
@ -0,0 +1,13 @@
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>
|
||||
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
@ -0,0 +1,40 @@
|
||||
# rollup-plugin-preprocessor
|
||||
A Rollup plugin that adds a C-like preprocessor to Javascript.
|
||||
|
||||
# Screenshots
|
||||
![Very useful comparison image (this is a lie)](assets/comparison.png)
|
||||
|
||||
# Documentation
|
||||
## Options
|
||||
This plugin exports a `preprocess()` plugin function that takes in an options object with the following syntax:
|
||||
```js
|
||||
{
|
||||
//a list of compile-time variables and their values (parsed to an AST, so all JS is valid)
|
||||
//NOTE: due to this, strings require single quotes around them to parse to String
|
||||
values: {
|
||||
EXAMPLE: "'Hello, world!'",
|
||||
IS_TRUE: 1,
|
||||
WEBPACK: "demon.summon('modules/webpack')"
|
||||
},
|
||||
//a list of comment transformations
|
||||
transforms: {
|
||||
//example: this deletes all comments that start with NONPROD in the output AST
|
||||
NONPROD: (node, parent, idx) => {parent.comments = []}
|
||||
}
|
||||
}
|
||||
```
|
||||
## Included Directives
|
||||
This plugin currently includes 3, battle-tested, production-ready directives for any code you may want to use them in.
|
||||
`#IF comptime_var` - If `comptime_var` evaluates to true, the code from it until the end is included in the output; otherwise, it is ignored.
|
||||
`#IFNOT comptime_var` - If `comptime_var` evaluates to false, the code from it until the end is included in the output; otherwise, it is ignored.
|
||||
`#END` - Ends an `#IF`/`#IFNOT` macro.
|
||||
|
||||
# Commonly Asked Questions
|
||||
## Why?
|
||||
I prefer doing things like this before runtime with compile-time constants, instead of on runtime with JS variables.
|
||||
## Are you insane?
|
||||
Yeah, probably.
|
||||
## Why not just use a Regex?
|
||||
I'm just #special like that.
|
||||
## Is this production ready?
|
||||
No.
|
After Width: | Height: | Size: 184 KiB |
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "rollup-plugin-preprocessor",
|
||||
"version": "1.0.0",
|
||||
"description": "A Rollup plugin that adds a C-like preprocessor to Javascript.",
|
||||
"main": "src/main.js",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"test": "pushd test; rollup -c"
|
||||
},
|
||||
"keywords": ["rollup", "rollup-plugin", "c", "preprocessor"],
|
||||
"author": "Ruthenic",
|
||||
"license": "WTFPL",
|
||||
"dependencies": {
|
||||
"estree-walker": "^3.0.1",
|
||||
"recast": "^0.21.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"rollup": "^2.78.1"
|
||||
}
|
||||
}
|
@ -0,0 +1,85 @@
|
||||
lockfileVersion: 5.4
|
||||
|
||||
specifiers:
|
||||
acorn: ^8.8.0
|
||||
estree-util-attach-comments: ^2.1.0
|
||||
estree-walker: ^3.0.1
|
||||
recast: ^0.21.2
|
||||
rollup: ^2.78.1
|
||||
|
||||
dependencies:
|
||||
acorn: 8.8.0
|
||||
estree-util-attach-comments: 2.1.0
|
||||
estree-walker: 3.0.1
|
||||
recast: 0.21.2
|
||||
rollup: 2.78.1
|
||||
|
||||
packages:
|
||||
|
||||
/@types/estree/1.0.0:
|
||||
resolution: {integrity: sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==}
|
||||
dev: false
|
||||
|
||||
/acorn/8.8.0:
|
||||
resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==}
|
||||
engines: {node: '>=0.4.0'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/ast-types/0.15.2:
|
||||
resolution: {integrity: sha512-c27loCv9QkZinsa5ProX751khO9DJl/AcB5c2KNtA6NRvHKS0PgLfcftz72KVq504vB0Gku5s2kUZzDBvQWvHg==}
|
||||
engines: {node: '>=4'}
|
||||
dependencies:
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/esprima/4.0.1:
|
||||
resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
|
||||
engines: {node: '>=4'}
|
||||
hasBin: true
|
||||
dev: false
|
||||
|
||||
/estree-util-attach-comments/2.1.0:
|
||||
resolution: {integrity: sha512-rJz6I4L0GaXYtHpoMScgDIwM0/Vwbu5shbMeER596rB2D1EWF6+Gj0e0UKzJPZrpoOc87+Q2kgVFHfjAymIqmw==}
|
||||
dependencies:
|
||||
'@types/estree': 1.0.0
|
||||
dev: false
|
||||
|
||||
/estree-walker/3.0.1:
|
||||
resolution: {integrity: sha512-woY0RUD87WzMBUiZLx8NsYr23N5BKsOMZHhu2hoNRVh6NXGfoiT1KOL8G3UHlJAnEDGmfa5ubNA/AacfG+Kb0g==}
|
||||
dev: false
|
||||
|
||||
/fsevents/2.3.2:
|
||||
resolution: {integrity: sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==}
|
||||
engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
|
||||
os: [darwin]
|
||||
requiresBuild: true
|
||||
dev: false
|
||||
optional: true
|
||||
|
||||
/recast/0.21.2:
|
||||
resolution: {integrity: sha512-jUR1+NtaBQdKDqBJ+qxwMm5zR8aLSNh268EfgAbY+EP4wcNEWb6hZFhFeYjaYanwgDahx5t47CH8db7X2NfKdQ==}
|
||||
engines: {node: '>= 4'}
|
||||
dependencies:
|
||||
ast-types: 0.15.2
|
||||
esprima: 4.0.1
|
||||
source-map: 0.6.1
|
||||
tslib: 2.4.0
|
||||
dev: false
|
||||
|
||||
/rollup/2.78.1:
|
||||
resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==}
|
||||
engines: {node: '>=10.0.0'}
|
||||
hasBin: true
|
||||
optionalDependencies:
|
||||
fsevents: 2.3.2
|
||||
dev: false
|
||||
|
||||
/source-map/0.6.1:
|
||||
resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
dev: false
|
||||
|
||||
/tslib/2.4.0:
|
||||
resolution: {integrity: sha512-d6xOpEDfsi2CZVlPQzGeux8XMwLT9hssAsaPYExaQMuYskwb+x1x7J371tWlbBdWHroy99KnVB6qIkUbs5X3UQ==}
|
||||
dev: false
|
@ -0,0 +1,96 @@
|
||||
import { walk } from 'estree-walker'
|
||||
import recast from 'recast'
|
||||
|
||||
//my thoughts on this code are: na na na nani the fuck
|
||||
export default function preprocess(opts) {
|
||||
return {
|
||||
name: "preprocess",
|
||||
transform: {
|
||||
order: 'pre',
|
||||
handler(code) {
|
||||
const state = {
|
||||
failedIf: false
|
||||
}
|
||||
const parse = this.parse
|
||||
|
||||
const comments = []
|
||||
const ast = recast.parse(code, {
|
||||
parser: this
|
||||
})
|
||||
walk(ast, { //WALK CST FOR COMPTIME_VARS
|
||||
enter(node, parent, prop, index) {
|
||||
if (parent?.type === "MemberExpression" && parent?.property === node) {
|
||||
if (state.failedIf) {
|
||||
delete parent[prop]
|
||||
}
|
||||
return //ignore childs of objects ie console.log
|
||||
} else if (node.type === "Identifier") {
|
||||
if (opts.values) {
|
||||
for (const i in opts.values) {
|
||||
if (i === node.name) {
|
||||
console.log(`Found comp-time var ${i} with value ${opts.values[i]}`)
|
||||
const res = eval(`(${opts.values[i]})`)
|
||||
if (typeof res === "string") {
|
||||
parent[prop] = [ parse(`('${res}')`).body[0].expression ]
|
||||
} else {
|
||||
parent[prop] = [ parse(`(${res})`).body[0].expression ]
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (node.comments) {
|
||||
node.comments.forEach((cmt, cidx) => {
|
||||
for (const i in opts.transforms) {
|
||||
if (cmt.value.startsWith(i)) {
|
||||
console.log(`Found comp-time comment transformation ${i}`)
|
||||
opts.transforms[i](cmt, node, cidx)
|
||||
return
|
||||
}
|
||||
}
|
||||
if (cmt.value.toUpperCase().startsWith("#IF ")) {
|
||||
const vari = cmt.value.substring(4)
|
||||
node.comments = []
|
||||
if (opts.values[vari] === undefined) {
|
||||
throw new Error("Cannot use undefined comp-time variable in #IF macro!")
|
||||
} else {
|
||||
const res = eval(`(${opts.values[vari]})`)
|
||||
if (!!res) {
|
||||
console.log("Broke into #IF macro")
|
||||
} else {
|
||||
console.log(`Unmet #IF for ${vari}`)
|
||||
state.failedIf = true
|
||||
}
|
||||
}
|
||||
} else if (cmt.value.toUpperCase().startsWith("#IFNOT ")) {
|
||||
const vari = cmt.value.substring(7)
|
||||
node.comments = []
|
||||
if (opts.values[vari] === undefined) {
|
||||
throw new Error("Cannot use undefined comp-time variable in #IFNOT macro!")
|
||||
} else {
|
||||
const res = eval(`(${opts.values[vari]})`)
|
||||
if (!res) {
|
||||
console.log("Broke into #IFNOT macro")
|
||||
} else {
|
||||
console.log(`Unmet #IFNOT for ${vari} at Line ${cmt.loc.start.line}:${cmt.loc.start.column}`)
|
||||
state.failedIf = true
|
||||
}
|
||||
}
|
||||
} else if (cmt.value.toUpperCase().startsWith("#END")) {
|
||||
console.log("Broke out of macro")
|
||||
node.comments = []
|
||||
state.failedIf = false
|
||||
}
|
||||
})
|
||||
} else {
|
||||
if (state.failedIf) {
|
||||
delete parent[prop]
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
return { code: recast.print(ast).code }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,6 @@
|
||||
console.log("Hello, world!");
|
||||
|
||||
console.log("#IF works");
|
||||
console.log("#IFNOT works");
|
||||
console.log("Hello, world!");
|
||||
console.log(2);
|
@ -0,0 +1,21 @@
|
||||
import preprocess from "../src/main.js"
|
||||
|
||||
export default {
|
||||
input: "./test.js",
|
||||
output: {
|
||||
file: "out.js"
|
||||
},
|
||||
plugins: [
|
||||
preprocess({
|
||||
values: {
|
||||
"COMPTIME_STR": "'Hello, world!'",
|
||||
"COMPTIME_NUM": 2,
|
||||
"IS_TRUE": 1,
|
||||
"IS_FALSE": 0
|
||||
},
|
||||
transforms: {
|
||||
"NONPROD": (node, parent, idx) => {parent.comments = []}
|
||||
}
|
||||
})
|
||||
]
|
||||
}
|
@ -0,0 +1,18 @@
|
||||
console.log("Hello, world!")
|
||||
|
||||
//#IF IS_TRUE
|
||||
console.log("#IF works")
|
||||
//#END
|
||||
//#IF IS_FALSE
|
||||
console.log("#IF does not work (ignore the last one if this shows up)")
|
||||
//#END
|
||||
|
||||
//#IfNoT IS_FALSE
|
||||
console.log("#IFNOT works")
|
||||
//#END
|
||||
//#ifnot IS_TRUE
|
||||
console.log("#IFNOT does not work (disregard prior)")
|
||||
//#end
|
||||
|
||||
console.log(COMPTIME_STR)
|
||||
console.log(COMPTIME_NUM)
|
Loading…
Reference in new issue