转换


\Transpilation

可以使用 load 钩子 将 Node.js 无法理解的格式的源代码转换为 JavaScript。

\Sources that are in formats Node.js doesn't understand can be converted into JavaScript using the load hook.

这比在运行 Node.js 之前转换源文件的性能要差;转译器钩子只能用于开发和测试目的。

\This is less performant than transpiling source files before running Node.js; transpiler hooks should only be used for development and testing purposes.

// coffeescript-hooks.mjs
import { readFile } from 'node:fs/promises';
import { dirname, extname, resolve as resolvePath } from 'node:path';
import { cwd } from 'node:process';
import { fileURLToPath, pathToFileURL } from 'node:url';
import coffeescript from 'coffeescript';
const extensionsRegex = /\.(coffee|litcoffee|coffee\.md)$/;
export async function load(url, context, nextLoad) {
 if (extensionsRegex.test(url)) {
 // CoffeeScript files can be either CommonJS or ES modules, so we want any
 // CoffeeScript file to be treated by Node.js the same as a .js file at the
 // same location. To determine how Node.js would interpret an arbitrary .js
 // file, search up the file system for the nearest parent package.json file
 // and read its "type" field.
 const format = await getPackageType(url);
 const { source: rawSource } = await nextLoad(url, { ...context, format });
 // This hook converts CoffeeScript source code into JavaScript source code
 // for all imported CoffeeScript files.
 const transformedSource = coffeescript.compile(rawSource.toString(), url);
 return {
 format,
 shortCircuit: true,
 source: transformedSource,
 };
 }
 // Let Node.js handle all other URLs.
 return nextLoad(url);
}
async function getPackageType(url) {
 // `url` is only a file path during the first iteration when passed the
 // resolved url from the load() hook
 // an actual file path from load() will contain a file extension as it's
 // required by the spec
 // this simple truthy check for whether `url` contains a file extension will
 // work for most projects but does not cover some edge-cases (such as
 // extensionless files or a url ending in a trailing space)
 const isFilePath = !!extname(url);
 // If it is a file path, get the directory it's in
 const dir = isFilePath ?
 dirname(fileURLToPath(url)) :
 url;
 // Compose a file path to a package.json in the same directory,
 // which may or may not exist
 const packagePath = resolvePath(dir, 'package.json');
 // Try to read the possibly nonexistent package.json
 const type = await readFile(packagePath, { encoding: 'utf8' })
 .then((filestring) => JSON.parse(filestring).type)
 .catch((err) => {
 if (err?.code !== 'ENOENT') console.error(err);
 });
 // If package.json existed and contained a `type` field with a value, voilà
 if (type) return type;
 // Otherwise, (if not at the root) continue checking the next directory up
 // If at the root, stop and return false
 return dir.length > 1 && getPackageType(resolvePath(dir, '..'));
} 
# main.coffee
import { scream } from './scream.coffee'
console.log scream 'hello, world'
import { version } from 'node:process'
console.log "Brought to you by Node.js version #{version}" 
# scream.coffee
export scream = (str) -> str.toUpperCase() 

使用前面的 hooks 模块,运行 node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./coffeescript-hooks.mjs"));' ./main.coffee 会导致 main.coffee 在其源代码从磁盘加载之后、Node.js 执行之前转换为 JavaScript;对于通过任何加载文件的 import 语句引用的任何 .coffee.litcoffee.coffee.md 文件,依此类推。

\With the preceding hooks module, running node --import 'data:text/javascript,import { register } from "node:module"; import { pathToFileURL } from "node:url"; register(pathToFileURL("./coffeescript-hooks.mjs"));' ./main.coffee causes main.coffee to be turned into JavaScript after its source code is loaded from disk but before Node.js executes it; and so on for any .coffee, .litcoffee or .coffee.md files referenced via import statements of any loaded file.

AltStyle によって変換されたページ (->オリジナル) /