Skip to content

Commit

Permalink
fixed build with mjs (esm)
Browse files Browse the repository at this point in the history
  • Loading branch information
HillLiu committed Sep 2, 2024
1 parent 185b5f3 commit c81daaf
Show file tree
Hide file tree
Showing 20 changed files with 254 additions and 142 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
"clean": "find ./build ./types -name '*.*' | xargs rm -rf",
"build:cjs": "BABEL_ENV=cjs babel src -d build/cjs --ignore /**/__tests__",
"build:es": "BABEL_ENV=es babel src -d build/es --out-file-extension .mjs",
"build:type": "npx -p typescript tsc src/*.js src/**/*.js src/ui/**/*.jsx --jsx react-jsx --declaration --allowJs --emitDeclarationOnly --skipLibCheck --declarationDir types",
"build:type": "npx -p typescript tsc src/*.js src/**/*.js src/ui/**/*.jsx --jsx react-jsx --declaration --allowJs --emitDeclarationOnly --skipLibCheck --module node16 --declarationDir types",
"build": "npm run clean && npm run build:cjs && npm run build:es && npm run build:type",
"mochaFor": "STRICT_MODE=1 mocha -r global-jsdom/register",
"mocha": "npm run mochaFor -- 'build/es/**/__tests__/*.mjs'",
Expand Down
30 changes: 21 additions & 9 deletions packages/reshow-app/package.build.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "0.18.0",
"version": "0.18.8",
"name": "reshow-app",
"repository": {
"type": "git",
Expand All @@ -16,7 +16,6 @@
"ansi-html-community": "0.0.8",
"array.polyfill": "*",
"call-func": "*",
"chalk": "5.3.0",
"core-js": "^3.1.4",
"error-stack-parser": "2.0.6",
"es6-promise": "4.2.5",
Expand Down Expand Up @@ -66,14 +65,24 @@
"import": "./server.mjs"
},
"./webpack.client": {
"types": "./types/webpack.client.d.ts",
"require": "./webpack.client.js",
"import": "./webpack.client.mjs"
"require": {
"types": "./types/webpack.client.d.ts",
"default": "./webpack.client.js"
},
"import": {
"types": "./types/webpack.client.d.ts",
"default": "./webpack.client.mjs"
}
},
"./webpack.server": {
"types": "./types/webpack.server.d.ts",
"require": "./webpack.server.js",
"import": "./webpack.server.mjs"
"require": {
"types": "./types/webpack.server.d.ts",
"default": "./webpack.server.js"
},
"import": {
"types": "./types/webpack.server.d.ts",
"default": "./webpack.server.mjs"
}
}
},
"scripts": {
Expand All @@ -90,8 +99,11 @@
"client.mjs",
"package.json",
"server.js",
"server.mjs",
"webpack",
"webpack.client.js",
"webpack.server.js"
"webpack.client.mjs",
"webpack.server.js",
"webpack.server.mjs"
]
}
5 changes: 2 additions & 3 deletions packages/reshow-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,15 @@
"license": "ISC",
"devDependencies": {
"@babel/cli": "^7.x",
"chalk": "5.3.0",
"reshow-unit": "*",
"webpack": "5.94.0"
},
"scripts": {
"copy": "cp package.build.json ./build/package.json && cp yarn.build.lock ./build/yarn.lock && cp -r {README.md,types} ./build",
"clean": "find ./build/* \\( ! -path \"*node_modules*\" \\) | xargs rm -rf",
"build:type": "npx -p typescript tsc src/*.js src/**/*.js --jsx react-jsx --declaration --allowJs --emitDeclarationOnly --skipLibCheck --declarationDir types",
"build:type": "npx -p typescript tsc src/*.js src/**/*.js --jsx react-jsx --declaration --allowJs --emitDeclarationOnly --skipLibCheck --module nodenext --declarationDir types",
"build:src": "BABEL_ENV=cjs babel src -d build --root-mode upward",
"build:client": "BABEL_ENV=es babel src/client.js src/server.js src/webpack.client.js src/webpack.server.js -d build --out-file-extension .mjs --root-mode upward",
"build:client": "BABEL_ENV=es babel src -d build --out-file-extension .mjs --root-mode upward",
"build:babel": "npm run build:src && npm run build:client",
"build:dev": "npm run build:type && npm run build:babel && npm run copy && cd build && yarn && npm run syncpkg",
"build": "npm run clean && npm run build:dev",
Expand Down
1 change: 0 additions & 1 deletion packages/reshow-app/src/webpack.server.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import webpack from "webpack";
import getResolve, { getResolveLoader } from "./webpack/getResolve";
import getEntry from "./webpack/getEntry";
import getOptimization from "./webpack/getOptimization";
Expand Down
10 changes: 4 additions & 6 deletions packages/reshow-app/src/webpack/getPlugins.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// @ts-check

import * as webpack from "webpack";
import chalk from "chalk";
import webpack from "webpack";

import FinishPlugin from "./FinishPlugin";
import getStatsJson from "./getStatsJson";
Expand All @@ -14,7 +13,7 @@ import { PRODUCTION } from "./const";

const { AggressiveMergingPlugin, LimitChunkCountPlugin } = webpack.optimize;
const assetsStore = { current: null };
const log = (/**@type string*/ s) => console.log(chalk.inverse(s));
const log = (/**@type string*/ s) => console.log(s);

/**
* @param {object} props
Expand Down Expand Up @@ -46,9 +45,8 @@ const getPlugins = ({
plugins.push(
new webpack.ProvidePlugin({
process: "process/browser.js",
ReadableStream: require.resolve(
root + "/node_modules/reshow-app/webpack/ReadableStream"
),
ReadableStream:
root + "/node_modules/reshow-app/webpack/ReadableStream",
})
);
}
Expand Down
4 changes: 2 additions & 2 deletions packages/reshow-app/src/webpack/getResolve.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ const getResolve = ({ confs, root }) => {

const fallback = {
...confs.fallback,
stream: require.resolve("readable-stream"),
util: require.resolve(`${nroot}/reshow-app/webpack/util/util`),
stream: `${nroot}/readable-stream/readable.js`,
util: `${nroot}/reshow-app/webpack/util/util`,
fs: false,
net: false,
tls: false,
Expand Down
5 changes: 4 additions & 1 deletion packages/reshow-app/src/webpack/refresh/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ import { getRefreshGlobalScope, refreshUtils } from "./globals";
import injectRefreshLoader from "./utils/injectRefreshLoader";
import injectRefreshEntry from "./utils/injectRefreshEntry";
import makeRefreshRuntimeModule from "./utils/makeRefreshRuntimeModule";
import { getDirName } from "../util/getDirName";

const root = getDirName();

/**
* @typedef {Object} ReactRefreshPluginOptions
Expand Down Expand Up @@ -51,7 +54,7 @@ class ReactRefreshPlugin {

// Inject refresh utilities to Webpack's global scope
const providePlugin = new webpack.ProvidePlugin({
[refreshUtils]: require.resolve("./runtime/utils"),
[refreshUtils]: `${root}/runtime/utils`,
});
providePlugin.apply(compiler);

Expand Down
1 change: 0 additions & 1 deletion packages/reshow-app/src/webpack/refresh/loader.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import fs from "fs";
import { refreshUtils } from "./globals";
import RefreshModuleRuntime from "./runtime/RefreshModuleRuntime";
import isUseEsm from "./utils/isUseEsm";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
import { expect } from "chai";
import { dirname, resolve } from "path";
import { resolve } from "path";

import isUseEsm, { pkgType } from "../isUseEsm";
import { getDirName } from "../../../util/getDirName";

let dir;

try {
_NOT_DEFINED;
} catch (e) {
const initiator = e.stack.split("\n").slice(1)[0];
const folder = /(?<path>[^\(\s]+):[0-9]+:[0-9]+/
.exec(initiator)
.groups.path.replace("file://", "");
dir = resolve(
dirname(folder),
"../../../../../src/webpack/refresh/utils/__tests__/",
);
}
const dir = resolve(
getDirName(),
"../../../../../src/webpack/refresh/utils/__tests__/"
);

describe("Test isUseEsm", () => {
beforeEach(() => (pkgType.current = null));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
/** @typedef {string | string[] | import('webpack').Entry} StaticEntry */
/** @typedef {StaticEntry | import('webpack').EntryFunc} WebpackEntry */

import { getDirName } from "../../util/getDirName";
const rootDir = getDirName();
import path from "path";

/**
* Injects an entry to the bundle for react-refresh.
* @param {WebpackEntry} [originalEntry] A Webpack entry object.
Expand All @@ -9,9 +13,9 @@
const injectRefreshEntry = (originalEntry) => {
const entryInjects = [
// React-refresh runtime
require.resolve("../runtime/ReactRefreshEntry"),
path.join(rootDir, "../runtime/ReactRefreshEntry"),
// Error overlay runtime
require.resolve("../runtime/ErrorOverlayEntry"),
path.join(rootDir, "../runtime/ErrorOverlayEntry"),
];

// Single string entry point
Expand All @@ -29,14 +33,14 @@ const injectRefreshEntry = (originalEntry) => {
...acc,
[curKey]: injectRefreshEntry(curEntry),
}),
{},
{}
);
}
// Dynamic entry points
if (typeof originalEntry === "function") {
return (...args) =>
Promise.resolve(originalEntry(...args)).then((resolvedEntry) =>
injectRefreshEntry(resolvedEntry),
injectRefreshEntry(resolvedEntry)
);
}

Expand Down
103 changes: 81 additions & 22 deletions packages/reshow-app/src/webpack/refresh/utils/injectRefreshLoader.js
Original file line number Diff line number Diff line change
@@ -1,34 +1,93 @@
// @ts-check
// https://github.com/pmmmwh/react-refresh-webpack-plugin/blob/f1c8b9a44198449093ca95f85af5df97925e1cfc/lib/utils/injectRefreshLoader.js

import path from "path";
import { createRequire } from "node:module";
import { getDirName } from "../../util/getDirName";

/**
* @typedef {Object} ESModuleOptions
* @property {string | RegExp | Array<string | RegExp>} [exclude] Files to explicitly exclude from flagged as ES Modules.
* @property {string | RegExp | Array<string | RegExp>} [include] Files to explicitly include for flagged as ES Modules.
*/

/**
* @typedef {Object} ReactRefreshLoaderOptions
* @property {boolean} [const] Enables usage of ES6 `const` and `let` in generated runtime code.
* @property {boolean | ESModuleOptions} [esModule] Enables strict ES Modules compatible runtime.
*/

/**
* @callback MatchObject
* @param {string} [str]
* @returns {boolean}
*/

/**
* @typedef {Object} InjectLoaderOptions
* @property {MatchObject} match A function to include/exclude files to be processed.
* @property {ReactRefreshLoaderOptions} [options] Options passed to the loader.
*/

const rootDir = getDirName();
let myrequire;
if ("undefined" === typeof require) {
// @ts-ignore
myrequire = createRequire(import.meta.url);
} else {
myrequire = require;
}

const resolvedLoader = path.join(rootDir, "../loader");
const reactRefreshPath = path.dirname(myrequire.resolve("react-refresh"));
const refreshUtilsPath = path.join(rootDir, "../runtime/RefreshUtils");

/**
* @param {any} moduleData
* @param {InjectLoaderOptions} injectOptions
*/
const injectRefreshLoader = (moduleData, injectOptions) => {
const { match, options } = injectOptions;
const resolvedLoader = require.resolve("../loader");

// Include and exclude user-specified files
if (!match(moduleData.matchResource || moduleData.resource)) {
return moduleData;
}

// Include and exclude dynamically generated modules from other loaders
if (moduleData.matchResource && !match(moduleData.request)) {
return moduleData;
}

// Exclude files referenced as assets
if (moduleData.type.includes("asset")) {
return moduleData;
}

// Check to prevent double injection
if (moduleData.loaders.find(({ loader }) => loader === resolvedLoader)) {
return moduleData;
}

// Skip react-refresh and the plugin's runtime utils to prevent self-referencing -
// this is useful when using the plugin as a direct dependency,
// or when node_modules are specified to be processed.
if (
// Include and exclude user-specified files
match(moduleData.matchResource || moduleData.resource) &&
// Exclude files referenced as assets
!moduleData.type.includes("asset") &&
// Skip react-refresh and the plugin's runtime utils to prevent self-referencing -
// this is useful when using the plugin as a direct dependency,
// or when node_modules are specified to be processed.
!moduleData.resource.includes(
path.dirname(require.resolve("react-refresh")),
) &&
!moduleData.resource.includes(path.join(__dirname, "../runtime")) &&
// Check to prevent double injection
!moduleData.loaders.find(({ loader }) => loader === resolvedLoader)
moduleData.resource.includes(reactRefreshPath) ||
moduleData.resource.includes(refreshUtilsPath)
) {
// As we inject runtime code for each module,
// it is important to run the injected loader after everything.
// This way we can ensure that all code-processing have been done,
// and we won't risk breaking tools like Flow or ESLint.
moduleData.loaders.unshift({
loader: resolvedLoader,
options,
});
return moduleData;
}

// As we inject runtime code for each module,
// it is important to run the injected loader after everything.
// This way we can ensure that all code-processing have been done,
// and we won't risk breaking tools like Flow or ESLint.
moduleData.loaders.unshift({
loader: resolvedLoader,
options,
});

return moduleData;
};
export default injectRefreshLoader;
19 changes: 19 additions & 0 deletions packages/reshow-app/src/webpack/util/getDirName.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// @ts-check

import { dirname } from "path";

export const getDirName = () => {
let rootDir = "";
try {
// @ts-expect-error
_NOT_DEFINED;
} catch (e) {
const initiator = e.stack.split("\n").slice(2)[0];
// @ts-ignore
const file = /(?<path>[^\(\s]+):[0-9]+:[0-9]+/
?.exec(initiator)
?.groups.path.replace("file://", "");
rootDir = dirname(file || "");
}
return rootDir;
};
16 changes: 10 additions & 6 deletions packages/reshow-app/src/webpack/util/support/types.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
// Currently in sync with Node.js lib/internal/util/types.js
// https://github.com/nodejs/node/commit/112cc7c27551254aa2b17098fb774867f05ed0d9

"use strict";
// @ts-check

var isArgumentsObject = require("is-arguments");
var isGeneratorFunction = require("is-generator-function");
var whichTypedArray = require("which-typed-array");
var isTypedArray = require("is-typed-array");
import isArgumentsObject from "is-arguments";
import isGeneratorFunction from "is-generator-function";
import whichTypedArray from "which-typed-array";
/**
* @param {any} a
* @returns {boolean}
*/
const isTypedArray = (a) => Array.isArray(a);

function uncurryThis(f) {
return f.call.bind(f);
Expand Down Expand Up @@ -223,7 +227,7 @@ function isSharedArrayBuffer(value) {

if (typeof isSharedArrayBufferToString.working === "undefined") {
isSharedArrayBufferToString.working = isSharedArrayBufferToString(
new SharedArrayBufferCopy(),
new SharedArrayBufferCopy()
);
}

Expand Down
Loading

0 comments on commit c81daaf

Please sign in to comment.