Skip to content

Commit

Permalink
fix: node10 support, remove globalThis references (#144)
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdbradley authored Jan 28, 2022
1 parent c4aa7c9 commit c3f27b7
Show file tree
Hide file tree
Showing 11 changed files with 96 additions and 56 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ Qwik is designed for the fastest possible page load time, by deliving pure HTML
Try out our starter:

```bash
npm init qwik
npm init qwik@latest
```

- Understand the difference between [resumable and replayable](https://github.com/BuilderIO/qwik/blob/main/docs/RESUMABLE.md) applications.
Expand Down
3 changes: 3 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -100,17 +100,20 @@
"bindings/qwik_wasm_bg.wasm",
"bindings/qwik.wasm.cjs",
"bindings/qwik.wasm.mjs",
"core/package.json",
"core.cjs",
"core.cjs.map",
"core.min.mjs",
"core.mjs",
"core.mjs.map",
"core.d.ts",
"jsx-runtime/package.json",
"jsx-runtime.cjs",
"jsx-runtime.cjs.map",
"jsx-runtime.mjs",
"jsx-runtime.mjs.map",
"jsx-runtime.d.ts",
"optimizer/package.json",
"optimizer.cjs",
"optimizer.mjs",
"optimizer.d.ts",
Expand Down
23 changes: 22 additions & 1 deletion scripts/package-json.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { BuildConfig, PackageJSON } from './util';
import { BuildConfig, ensureDir, PackageJSON } from './util';
import { readFile, writeFile } from './util';
import { join } from 'path';

Expand Down Expand Up @@ -69,9 +69,30 @@ export async function generatePackageJson(config: BuildConfig) {

await writePackageJson(config.distPkgDir, distPkg);

await generateLegacyCjsSubmodule(config, 'core');
await generateLegacyCjsSubmodule(config, 'jsx-runtime');
await generateLegacyCjsSubmodule(config, 'optimizer');

console.log(`🐷 generated package.json`);
}

export async function generateLegacyCjsSubmodule(config: BuildConfig, pkgName: string) {
// Modern nodejs will resolve the submodule packages using "exports": https://nodejs.org/api/packages.html#subpath-exports
// however, legacy nodejs still needs a directory and its own package.json
// this can be removed once node12 is in the distant past
const pkg: PackageJSON = {
name: `@builder.io/qwik/${pkgName}`,
version: config.distVersion,
main: `../${pkgName}.cjs`,
module: `../${pkgName}.mjs`,
types: `../${pkgName}.d.ts`,
private: true,
};
const submoduleDistDir = join(config.distPkgDir, pkgName);
ensureDir(submoduleDistDir);
await writePackageJson(submoduleDistDir, pkg);
}

export async function readPackageJson(pkgJsonDir: string) {
const pkgJsonPath = join(pkgJsonDir, 'package.json');
const pkgJson: PackageJSON = JSON.parse(await readFile(pkgJsonPath, 'utf-8'));
Expand Down
32 changes: 18 additions & 14 deletions scripts/submodule-core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,8 +67,8 @@ async function submoduleCoreProd(config: BuildConfig) {

console.log('🦊 core.mjs:', await fileSize(join(config.distPkgDir, 'core.mjs')));

const esmCode = await readFile(join(config.distPkgDir, 'core.mjs'), 'utf-8');
const minifyResult = await minify(esmCode, {
let esmCode = await readFile(join(config.distPkgDir, 'core.mjs'), 'utf-8');
const esmMinifyResult = await minify(esmCode, {
module: true,
compress: {
global_defs: {
Expand All @@ -88,25 +88,29 @@ async function submoduleCoreProd(config: BuildConfig) {
},
});

const minFile = join(config.distPkgDir, 'core.min.mjs');
const minCode = minifyResult.code!;
await writeFile(minFile, minCode);
const cleanCode = minCode.replace(/__self__/g, '__SELF__');
const esmMinFile = join(config.distPkgDir, 'core.min.mjs');
const esmMinCode = esmMinifyResult.code!;
await writeFile(esmMinFile, esmMinCode);
const esmCleanCode = esmMinCode.replace(/__self__/g, '__SELF__');

const windowIdx = cleanCode.indexOf('window');
const selfIdx =
cleanCode.indexOf(
'self'
); /* || minCode.includes('global') // TODO(OPTIMIZER): Disable temporarily to make the tests work*/
const windowIdx = esmCleanCode.indexOf('window');
const selfIdx = esmCleanCode.indexOf('self');
const indx = Math.max(windowIdx, selfIdx);
if (indx !== -1) {
throw new Error(
`"${minFile}" should not have any global references, and should have been removed for a production minified build\n` +
cleanCode.substring(indx, indx + 20)
`"${esmMinFile}" should not have any global references, and should have been removed for a production minified build\n` +
esmCleanCode.substring(indx, indx + 20)
);
}
console.log('🐭 core.min.mjs:', await fileSize(esmMinFile));

console.log('🐭 core.min.mjs:', await fileSize(minFile));
esmCode = esmCode.replace(/globalThis\.qDev \!== false/g, 'true');
await writeFile(join(config.distPkgDir, 'core.mjs'), esmCode);

// always set the cjs version (probably imported serverside) to dev mode
let cjsCode = await readFile(join(config.distPkgDir, 'core.cjs'), 'utf-8');
cjsCode = cjsCode.replace(/globalThis\.qDev \!== false/g, 'true');
await writeFile(join(config.distPkgDir, 'core.cjs'), cjsCode);
}

async function submoduleCoreDev(config: BuildConfig) {
Expand Down
2 changes: 1 addition & 1 deletion src/optimizer/src/optimizer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ const transformFsVirtual = async (sys: InternalSystem, opts: TransformFsOptions)
async function getFiles(dir: string) {
const subdirs = await readDir(sys, dir);
const files: string[] = await Promise.all(
subdirs.flatMap(async (subdir: any) => {
subdirs.map(async (subdir: any) => {
const res = sys.path.resolve(dir, subdir);
const isDir = await isDirectory(sys, res);
return (isDir ? getFiles(res) : res) as any;
Expand Down
11 changes: 11 additions & 0 deletions src/optimizer/src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,17 @@ export async function getSystem() {
// using this api object as a way to ensure bundlers
// do not try to inline or rewrite require()
sys.dynamicImport = (path) => require(path);

if (typeof globalThis === 'undefined') {
global.globalThis = global;
}
if (typeof TextEncoder === 'undefined') {
// TextEncoder/TextDecoder needs to be on the global scope for the WASM file
// https://nodejs.org/api/util.html#class-utiltextdecoder
const nodeUtil: any = sys.dynamicImport('util');
global.TextEncoder = nodeUtil.TextEncoder;
global.TextDecoder = nodeUtil.TextDecoder;
}
}

if (sys.isNode) {
Expand Down
37 changes: 19 additions & 18 deletions src/optimizer/src/rollup/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -115,26 +115,27 @@ export function qwikRollup(opts: QwikPluginOptions = {}): any {
const output = Object.entries(rollupBundle);

const outputEntryMap: OutputEntryMap = {
mapping: Object.fromEntries(
result.hooks.map((h) => {
const symbolName = h.name;
let filename = h.canonicalFilename;
// eslint-disable-next-line
const found = output.find(([_, v]) => {
return (
v.type == 'chunk' &&
v.isDynamicEntry === true &&
Object.keys(v.modules).find((f) => f.endsWith(filename))
);
});
if (found) {
filename = found[0];
}
return [symbolName, filename];
})
),
mapping: {},
version: '1',
};

result.hooks.forEach((h) => {
const symbolName = h.name;
let filename = h.canonicalFilename;
// eslint-disable-next-line
const found = output.find(([_, v]) => {
return (
v.type == 'chunk' &&
v.isDynamicEntry === true &&
Object.keys(v.modules).find((f) => f.endsWith(filename))
);
});
if (found) {
filename = found[0];
}
outputEntryMap.mapping[symbolName] = filename;
});

if (typeof opts.symbolsOutput === 'string') {
this.emitFile({
fileName: opts.symbolsOutput,
Expand Down
10 changes: 5 additions & 5 deletions starters/apps/starter-builder/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { nodeResolve } from '@rollup/plugin-node-resolve';
import typescript from '@rollup/plugin-typescript';
import { qwikRollup } from '@builder.io/qwik/optimizer';
import { writeFile, mkdir } from "fs/promises";
import { dirname } from "path";
import { writeFileSync, mkdirSync } from 'fs';
import { dirname } from 'path';

export default async function () {
return {
Expand Down Expand Up @@ -34,7 +34,7 @@ export default async function () {
};
}

async function outputJSON(path, data) {
await mkdir(dirname(path), {recursive: true});
await writeFile(path, JSON.stringify(data, null, 2));
function outputJSON(path, data) {
mkdirSync(dirname(path), { recursive: true });
writeFileSync(path, JSON.stringify(data, null, 2));
}
10 changes: 5 additions & 5 deletions starters/apps/starter-partytown/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { nodeResolve } from '@rollup/plugin-node-resolve';
import typescript from '@rollup/plugin-typescript';
import { qwikRollup } from '@builder.io/qwik/optimizer';
import { writeFile, mkdir } from "fs/promises";
import { dirname } from "path";
import { writeFileSync, mkdirSync } from 'fs';
import { dirname } from 'path';

export default async function () {
return {
Expand Down Expand Up @@ -34,7 +34,7 @@ export default async function () {
};
}

async function outputJSON(path, data) {
await mkdir(dirname(path), {recursive: true});
await writeFile(path, JSON.stringify(data, null, 2));
function outputJSON(path, data) {
mkdirSync(dirname(path), { recursive: true });
writeFileSync(path, JSON.stringify(data, null, 2));
}
10 changes: 5 additions & 5 deletions starters/apps/starter/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { nodeResolve } from '@rollup/plugin-node-resolve';
import typescript from '@rollup/plugin-typescript';
import { qwikRollup } from '@builder.io/qwik/optimizer';
import { writeFile, mkdir } from "fs/promises";
import { dirname } from "path";
import { writeFileSync, mkdirSync } from 'fs';
import { dirname } from 'path';

export default async function () {
return {
Expand Down Expand Up @@ -34,7 +34,7 @@ export default async function () {
};
}

async function outputJSON(path, data) {
await mkdir(dirname(path), {recursive: true});
await writeFile(path, JSON.stringify(data, null, 2));
function outputJSON(path, data) {
mkdirSync(dirname(path), { recursive: true });
writeFileSync(path, JSON.stringify(data, null, 2));
}
12 changes: 6 additions & 6 deletions starters/apps/todo/rollup.config.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { nodeResolve } from '@rollup/plugin-node-resolve';
import typescript from '@rollup/plugin-typescript';
import { qwikRollup } from '@builder.io/qwik/optimizer';
import { terser } from "rollup-plugin-terser";
import { writeFile, mkdir } from "fs/promises";
import { dirname } from "path";
import { terser } from 'rollup-plugin-terser';
import { writeFileSync, mkdirSync } from 'fs';
import { dirname } from 'path';

export default async function () {
return {
Expand Down Expand Up @@ -36,7 +36,7 @@ export default async function () {
};
}

async function outputJSON(path, data) {
await mkdir(dirname(path), {recursive: true});
await writeFile(path, JSON.stringify(data, null, 2));
function outputJSON(path, data) {
mkdirSync(dirname(path), { recursive: true });
writeFileSync(path, JSON.stringify(data, null, 2));
}

0 comments on commit c3f27b7

Please sign in to comment.