Skip to content

Commit

Permalink
Added CJS output and source maps
Browse files Browse the repository at this point in the history
  • Loading branch information
RunDevelopment committed May 31, 2023
1 parent 55943eb commit 2c4e9e5
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 34 deletions.
22 changes: 22 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Expand Up @@ -64,6 +64,7 @@
"gzip-size": "^5.1.1",
"htmlparser2": "^4.0.0",
"jsdom": "^16.7.0",
"magic-string": "^0.30.0",
"mocha": "^9.2.2",
"mocha-chai-jest-snapshot": "^1.1.4",
"npm-run-all": "^4.1.5",
Expand Down
100 changes: 67 additions & 33 deletions scripts/build.ts
Expand Up @@ -3,6 +3,7 @@ import rollupTypescript from '@rollup/plugin-typescript';
import CleanCSS from 'clean-css';
import fs from 'fs';
import { mkdir, readFile, readdir, rm, writeFile, } from 'fs/promises';
import MagicString from 'magic-string';
import path from 'path';
import { rollup } from 'rollup';
import { terser as rollupTerser } from 'rollup-plugin-terser';
Expand All @@ -11,7 +12,7 @@ import { toArray } from '../src/shared/util';
import { components } from './components';
import { parallel, runTask, series } from './tasks';
import type { ComponentProto } from '../src/types';
import type { OutputOptions, Plugin } from 'rollup';
import type { Plugin, SourceMapInput } from 'rollup';


const SRC_DIR = path.join(__dirname, '../src/');
Expand Down Expand Up @@ -41,7 +42,7 @@ async function minifyCSS() {
for (const id of pluginIds) {
const file = path.join(SRC_DIR, `plugins/${id}/prism-${id}.css`);
if (fs.existsSync(file)) {
input[`plugins/${id}/prism-${id}.css`] = file;
input[`plugins/prism-${id}.css`] = file;
}
}

Expand Down Expand Up @@ -165,37 +166,43 @@ const dataToInsert = {
const dataInsertPlugin: Plugin = {
name: 'data-insert',
async renderChunk(code, chunk) {
const placeholderPattern = /\/\*\s*(\w+)\[\s*\*\/[\s\S]*?\/\*\s*\]\s*\*\//g;
const pattern = /\/\*\s*(\w+)\[\s*\*\/[\s\S]*?\/\*\s*\]\s*\*\//g;

let result = '';
let last = 0;
// search for placeholders
const contained = new Set<string>();
let m;
while ((m = pattern.exec(code))) {
contained.add(m[1]);
}

while ((m = placeholderPattern.exec(code))) {
const [, name] = m;
if (name in dataToInsert) {
result += code.slice(last, m.index);
last = m.index + m[0].length;
if (contained.size === 0) {
return null;
}

const data = await dataToInsert[name as keyof typeof dataToInsert]();
result += JSON.stringify(data);
// fetch placeholder data
const dataByName: Record<string, unknown> = {};
for (const name of contained) {
if (name in dataToInsert) {
dataByName[name] = await dataToInsert[name as keyof typeof dataToInsert]();
} else {
throw new Error(`Unknown placeholder ${name} in ${chunk.fileName}`);
}
}

if (last < code.length) {
result += code.slice(last);
}
return result;
// replace placeholders
const str = new MagicString(code);
str.replace(pattern, (_, name: string) => {
return JSON.stringify(dataByName[name]);
});
return toRenderedChunk(str);
},

};

const inlineRegexSourcePlugin: Plugin = {
name: 'inline-regex-source',
renderChunk(code) {
return code.replace(
const str = new MagicString(code);
str.replace(
/\/((?:[^\n\r[\\\/]|\\.|\[(?:[^\n\r\\\]]|\\.)*\])+)\/\s*\.\s*source\b/g,
(m, source: string) => {
// escape backslashes
Expand All @@ -219,6 +226,7 @@ const inlineRegexSourcePlugin: Plugin = {
return "'" + source + "'";
}
);
return toRenderedChunk(str);
},
};

Expand All @@ -234,13 +242,22 @@ const inlineRegexSourcePlugin: Plugin = {
const lazyGrammarPlugin: Plugin = {
name: 'lazy-grammar',
renderChunk(code) {
return code.replace(
const str = new MagicString(code);
str.replace(
/^(?<indent>[ \t]+)grammar: (\{[\s\S]*?^\k<indent>\})/m,
(m, _, grammar: string) => `\tgrammar: () => (${grammar})`
);
return toRenderedChunk(str);
},
};

function toRenderedChunk(s: MagicString): { code: string; map: SourceMapInput } {
return {
code: s.toString(),
map: s.generateMap({ hires: true }) as SourceMapInput,
};
}

const terserPlugin = rollupTerser({
ecma: 2015,
module: true,
Expand Down Expand Up @@ -271,28 +288,45 @@ async function buildJS() {
input[`languages/prism-${id}`] = path.join(SRC_DIR, `languages/prism-${id}.ts`);
}
for (const id of pluginIds) {
input[`plugins/${id}/prism-${id}`] = path.join(SRC_DIR, `plugins/${id}/prism-${id}.ts`);
input[`plugins/prism-${id}`] = path.join(SRC_DIR, `plugins/${id}/prism-${id}.ts`);
}

const outputOptions: OutputOptions = {
dir: 'dist',
chunkFileNames: '_chunks/[name]-[hash].js',
validate: true,
plugins: [
lazyGrammarPlugin,
dataInsertPlugin,
inlineRegexSourcePlugin,
terserPlugin
]
};

let bundle;
try {
bundle = await rollup({
input,
plugins: [rollupTypescript({ module: 'esnext' })],
});
await bundle.write(outputOptions);

// ESM
await bundle.write({
dir: 'dist/esm',
chunkFileNames: '_chunks/[name]-[hash].js',
validate: true,
sourcemap: 'hidden',
plugins: [
lazyGrammarPlugin,
dataInsertPlugin,
inlineRegexSourcePlugin,
terserPlugin
]
});

// CommonJS
await bundle.write({
dir: 'dist/cjs',
chunkFileNames: '_chunks/[name]-[hash].js',
validate: true,
sourcemap: 'hidden',
format: 'cjs',
exports: 'named',
plugins: [
lazyGrammarPlugin,
dataInsertPlugin,
inlineRegexSourcePlugin,
terserPlugin
]
});
} finally {
await bundle?.close();
}
Expand Down
2 changes: 1 addition & 1 deletion tsconfig.json
Expand Up @@ -11,7 +11,7 @@
// "disableReferencedProjectLoad": true, /* Reduce the number of projects loaded automatically by TypeScript. */

/* Language and Environment */
"target": "es2018", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
"target": "es2019", /* Set the JavaScript language version for emitted JavaScript and include compatible library declarations. */
// "lib": [], /* Specify a set of bundled library declaration files that describe the target runtime environment. */
// "jsx": "preserve", /* Specify what JSX code is generated. */
// "experimentalDecorators": true, /* Enable experimental support for TC39 stage 2 draft decorators. */
Expand Down

0 comments on commit 2c4e9e5

Please sign in to comment.