Skip to content

Instantly share code, notes, and snippets.

@nexpr

nexpr/index.js Secret

Last active October 10, 2020 12:13
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nexpr/13984039d756ed5d51a7cf11d317ddd4 to your computer and use it in GitHub Desktop.
Save nexpr/13984039d756ed5d51a7cf11d317ddd4 to your computer and use it in GitHub Desktop.
tplb
#!/usr/bin/env node
const fs = require("fs")
const path = require("path")
const acorn = require("acorn")
const walk = require("acorn-walk")
const getDirFiles = (dir) =>
fs
.readdirSync(dir, { withFileTypes: true })
.filter((e) => e.isFile())
.map((e) => e.name)
const checkDir = (dir) => {
try {
if (fs.statSync(dir).isDirectory()) return true
} catch (err) {}
throw new Error(`"${dir}" フォルダがみつかりませんでした`)
}
const createRequirePath = (from_dir, to_dir, name) => {
const dir = path.relative(from_dir, to_dir) || "."
return dir + path.sep + name
}
const build = (src, dst, helper) => {
for (const dir of [src, dst, helper]) checkDir(dir)
const helpers = getDirFiles(helper)
for (const name of getDirFiles(src)) {
const filepath = path.join(src, name)
const tpl = fs.readFileSync(filepath).toString().trim()
const ext = path.extname(name).slice(1)
const js = ext + "`" + tpl + "`"
let tree
try {
tree = acorn.parse(js, { ecmaVersion: 2020 })
} catch (err) {
console.error(`"${filepath}" ファイルにエラーがあります`)
throw err
}
const requires = new Set()
walk.simple(tree, {
Identifier(node) {
if (node.name !== "$") {
requires.add(node.name)
}
},
})
const require_code = Array.from(requires, (name) => {
const jsname = name + ".js"
const is_helper = helpers.includes(name + ".js")
const module_path = createRequirePath(dst, is_helper ? helper : dst, jsname)
return `const ${name} = require(${JSON.stringify(module_path)})\n`
}).join("")
const output_js = require_code + `module.exports = $ => ({ [ext]: ${js} })`
const output_name = name.slice(0, -path.extname(name).length) + ".js"
fs.writeFileSync(path.join(dst, output_name), output_js)
}
}
if (require.main === module) {
const { options } = process.argv.slice(2).reduce(
(a, b) => {
if (b === "--src") {
a.ctx = "src"
} else if (b === "--dst") {
a.ctx = "dst"
} else if (b === "--helper") {
a.ctx = "helper"
} else if (b === "--help") {
a.options.help = true
a.ctx = null
} else {
if (a.ctx) {
a.options[a.ctx] = b
a.ctx = null
} else {
console.error(`コマンドライン引数エラー:`, b)
a.options.help = true
}
}
return a
},
{
options: {},
ctx: null,
}
)
if (options.help) {
console.log(" Usage:")
console.log(" node <thisfile> --src /path/to/src --dst /path/to/dst --helper /path/to/helper")
return
}
const src = path.resolve(options.src || "src")
const dst = path.resolve(options.dst || "dst")
const helper = path.resolve(options.helper || "helper")
console.log("src: ", src)
console.log("dst: ", dst)
console.log("helper: ", helper)
build(src, dst, helper)
console.log("done")
}
{
"dependencies": {
"acorn": "^6.4.2",
"acorn-walk": "^8.0.0"
},
"name": "tplb",
"version": "0.0.1",
"bin": "index.js"
}
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
acorn-walk@^8.0.0:
version "8.0.0"
resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-8.0.0.tgz#56ae4c0f434a45fff4a125e7ea95fa9c98f67a16"
integrity sha512-oZRad/3SMOI/pxbbmqyurIx7jHw1wZDcR9G44L8pUVFEomX/0dH89SrM1KaDXuv1NpzAXz6Op/Xu/Qd5XXzdEA==
acorn@^6.4.2:
version "6.4.2"
resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.2.tgz#35866fd710528e92de10cf06016498e47e39e1e6"
integrity sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ==
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment