From e8d4e331894b1a3ed4749e9b9dabb3101e47d31b Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Fri, 16 Jun 2023 12:29:01 -0700 Subject: [PATCH 1/4] Fixes to make webframeworks work for plugin --- firebase-vscode/webpack.common.js | 31 +++++++++++++++++++++++++++++++ firebase-vscode/webpack.prod.js | 13 +++++++++++-- src/frameworks/constants.ts | 26 +------------------------- src/frameworks/index.ts | 2 +- src/frameworks/utils.ts | 4 ++++ 5 files changed, 48 insertions(+), 28 deletions(-) diff --git a/firebase-vscode/webpack.common.js b/firebase-vscode/webpack.common.js index ca1e75761e2..a188fc55a77 100644 --- a/firebase-vscode/webpack.common.js +++ b/firebase-vscode/webpack.common.js @@ -85,6 +85,37 @@ const extensionConfig = { ], }, }, + { + test: /frameworks\/utils\.ts$/, + loader: "string-replace-loader", + options: { + multiple: [ + { + search: "require.resolve", + replace: "__non_webpack_require__.resolve", + strict: true + }, + { + search: "require(path", + replace: '__non_webpack_require__(path', + strict: true, + }, + ], + }, + }, + { + test: /dynamicImport.js$/, + loader: "string-replace-loader", + options: { + multiple: [ + { + search: "require.resolve", + replace: "__non_webpack_require__.resolve", + strict: true + }, + ], + }, + }, ], }, plugins: [ diff --git a/firebase-vscode/webpack.prod.js b/firebase-vscode/webpack.prod.js index e4bb4e4b10f..75a648edc85 100644 --- a/firebase-vscode/webpack.prod.js +++ b/firebase-vscode/webpack.prod.js @@ -1,7 +1,16 @@ const { merge } = require("webpack-merge"); +const TerserPlugin = require("terser-webpack-plugin"); const common = require("./webpack.common.js"); module.exports = common.map(config => merge(config, { - mode: "production" + mode: "production", + optimization: { + minimize: true, + minimizer: [new TerserPlugin({ + terserOptions: { + keep_classnames: /AbortSignal/, + keep_fnames: /AbortSignal/ + } + }), '...'] + } })); - diff --git a/src/frameworks/constants.ts b/src/frameworks/constants.ts index 1b424cb187c..63cc6cd18b0 100644 --- a/src/frameworks/constants.ts +++ b/src/frameworks/constants.ts @@ -1,6 +1,4 @@ -import { readdirSync, statSync } from "fs"; -import { join } from "path"; -import { Framework, SupportLevel } from "./interfaces"; +import { SupportLevel } from "./interfaces"; import * as clc from "colorette"; export const NPM_COMMAND_TIMEOUT_MILLIES = 10_000; @@ -47,28 +45,6 @@ export const ALLOWED_SSR_REGIONS = [ export const I18N_ROOT = "/"; -export const WebFrameworks: Record = Object.fromEntries( - readdirSync(__dirname) - .filter((path) => statSync(join(__dirname, path)).isDirectory()) - .map((path) => { - // If not called by the CLI, (e.g., by the VS Code Extension) - // __dirname won't refer to this folder and these files won't be available. - // Instead it may find sibling folders that aren't modules, and this - // require will throw. - // Long term fix may be to bundle this instead of reading files at runtime - // but for now, this prevents crashing. - try { - return [path, require(join(__dirname, path))]; - } catch (e) { - return []; - } - }) - .filter( - ([, obj]) => - obj && obj.name && obj.discover && obj.build && obj.type !== undefined && obj.support - ) -); - export function GET_DEFAULT_BUILD_TARGETS() { return Promise.resolve(["production", "development"]); } diff --git a/src/frameworks/index.ts b/src/frameworks/index.ts index 42509442101..8ac1b3bf9c8 100644 --- a/src/frameworks/index.ts +++ b/src/frameworks/index.ts @@ -39,7 +39,6 @@ import { NODE_VERSION, SupportLevelWarnings, VALID_ENGINES, - WebFrameworks, } from "./constants"; import { BUILD_TARGET_PURPOSE, @@ -54,6 +53,7 @@ import { ensureTargeted } from "../functions/ensureTargeted"; import { isDeepStrictEqual } from "util"; import { resolveProjectPath } from "../projectPath"; import { logger } from "../logger"; +import { WebFrameworks } from "./frameworks"; export { WebFrameworks }; diff --git a/src/frameworks/utils.ts b/src/frameworks/utils.ts index 4c139fc9ab3..5c569adba65 100644 --- a/src/frameworks/utils.ts +++ b/src/frameworks/utils.ts @@ -246,10 +246,14 @@ export function relativeRequire(dir: string, mod: "@nuxt/kit"): Promise; */ export function relativeRequire(dir: string, mod: string) { try { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore prevent VSCE webpack from erroring on non_webpack_require const path = require.resolve(mod, { paths: [dir] }); if (extname(path) === ".mjs") { return dynamicImport(pathToFileURL(path).toString()); } else { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore prevent VSCE webpack from erroring on non_webpack_require return require(path); } } catch (e) { From 1b36f756dd627113262e16f5b672d420434117a2 Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Fri, 16 Jun 2023 13:54:29 -0700 Subject: [PATCH 2/4] Add comment about fragile replace --- src/frameworks/utils.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/frameworks/utils.ts b/src/frameworks/utils.ts index 5c569adba65..b8f5a12ba25 100644 --- a/src/frameworks/utils.ts +++ b/src/frameworks/utils.ts @@ -252,6 +252,9 @@ export function relativeRequire(dir: string, mod: string) { if (extname(path) === ".mjs") { return dynamicImport(pathToFileURL(path).toString()); } else { + // The VSCode plugin is searching for the string "require(path" for + // the string replacement described below - if this code is changed, + // make sure to change firebase-vscode/webpack.common.js // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore prevent VSCE webpack from erroring on non_webpack_require return require(path); From 6b673a09ea29b50842ea6754d8a1857100ead127 Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Fri, 16 Jun 2023 14:49:56 -0700 Subject: [PATCH 3/4] Switch to using conditional for __non_webpack_require__ --- firebase-vscode/tsconfig.json | 2 +- firebase-vscode/webpack.common.js | 31 ------------------------------- 2 files changed, 1 insertion(+), 32 deletions(-) diff --git a/firebase-vscode/tsconfig.json b/firebase-vscode/tsconfig.json index 1fff794824a..d13ff9f0c38 100644 --- a/firebase-vscode/tsconfig.json +++ b/firebase-vscode/tsconfig.json @@ -5,7 +5,7 @@ "allowSyntheticDefaultImports": true, "resolveJsonModule": true, "typeRoots": ["node_modules/@types", "../src/types"], - "module": "ES2015", + "module": "es2020", "moduleResolution": "node", "target": "ES2020", "outDir": "dist", diff --git a/firebase-vscode/webpack.common.js b/firebase-vscode/webpack.common.js index a188fc55a77..ca1e75761e2 100644 --- a/firebase-vscode/webpack.common.js +++ b/firebase-vscode/webpack.common.js @@ -85,37 +85,6 @@ const extensionConfig = { ], }, }, - { - test: /frameworks\/utils\.ts$/, - loader: "string-replace-loader", - options: { - multiple: [ - { - search: "require.resolve", - replace: "__non_webpack_require__.resolve", - strict: true - }, - { - search: "require(path", - replace: '__non_webpack_require__(path', - strict: true, - }, - ], - }, - }, - { - test: /dynamicImport.js$/, - loader: "string-replace-loader", - options: { - multiple: [ - { - search: "require.resolve", - replace: "__non_webpack_require__.resolve", - strict: true - }, - ], - }, - }, ], }, plugins: [ From c8cc3cc620732f519679b51d3e3976aef533b64f Mon Sep 17 00:00:00 2001 From: Christina Holland Date: Fri, 16 Jun 2023 14:50:05 -0700 Subject: [PATCH 4/4] Switch to using conditional for __non_webpack_require__ --- src/dynamicImport.js | 12 +++++++++++- src/frameworks/utils.ts | 18 +++++++++++------- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/dynamicImport.js b/src/dynamicImport.js index bad9d0d2b9c..8061b0a23ac 100644 --- a/src/dynamicImport.js +++ b/src/dynamicImport.js @@ -1,10 +1,20 @@ const { pathToFileURL } = require("url"); +// If being compiled with webpack, use non webpack require for these calls. +// (VSCode plugin uses webpack which by default replaces require calls +// with its own require, which doesn't work on files) +// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment +const requireFunc = + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore prevent VSCE webpack from erroring on non_webpack_require + // eslint-disable-next-line camelcase + typeof __webpack_require__ === "function" ? __non_webpack_require__ : require; + exports.dynamicImport = function(mod) { if (mod.startsWith("file://")) return import(mod); if (mod.startsWith("/")) return import(pathToFileURL(mod).toString()); try { - const path = require.resolve(mod); + const path = requireFunc.resolve(mod); return import(pathToFileURL(path).toString()); } catch(e) { return Promise.reject(e); diff --git a/src/frameworks/utils.ts b/src/frameworks/utils.ts index b8f5a12ba25..6967534c740 100644 --- a/src/frameworks/utils.ts +++ b/src/frameworks/utils.ts @@ -246,18 +246,22 @@ export function relativeRequire(dir: string, mod: "@nuxt/kit"): Promise; */ export function relativeRequire(dir: string, mod: string) { try { + // If being compiled with webpack, use non webpack require for these calls. + // (VSCode plugin uses webpack which by default replaces require calls + // with its own require, which doesn't work on files) + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + const requireFunc: typeof require = + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore prevent VSCE webpack from erroring on non_webpack_require + // eslint-disable-next-line camelcase + typeof __webpack_require__ === "function" ? __non_webpack_require__ : require; // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore prevent VSCE webpack from erroring on non_webpack_require - const path = require.resolve(mod, { paths: [dir] }); + const path = requireFunc.resolve(mod, { paths: [dir] }); if (extname(path) === ".mjs") { return dynamicImport(pathToFileURL(path).toString()); } else { - // The VSCode plugin is searching for the string "require(path" for - // the string replacement described below - if this code is changed, - // make sure to change firebase-vscode/webpack.common.js - // eslint-disable-next-line @typescript-eslint/ban-ts-comment - // @ts-ignore prevent VSCE webpack from erroring on non_webpack_require - return require(path); + return requireFunc(path); } } catch (e) { const path = relative(process.cwd(), dir);