UNPKG

@enonic/react4xp

Version:
369 lines (357 loc) 13.7 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/webpack.config.globals.ts var webpack_config_globals_exports = {}; __export(webpack_config_globals_exports, { default: () => webpack_config_globals_default }); module.exports = __toCommonJS(webpack_config_globals_exports); var import_fs2 = require("fs"); var import_path = require("path"); var import_chunks_2_json_webpack_plugin = __toESM(require("chunks-2-json-webpack-plugin")); // src/constants.runtime.ts var GLOBALS_FILENAME = "globals.json"; var R4X_TARGETSUBDIR = "r4xAssets"; // src/constants.buildtime.ts var DIR_PATH_RELATIVE_SRC_MAIN_RESOURCES = "src/main/resources"; var DIR_PATH_RELATIVE_SRC_R4X = `${DIR_PATH_RELATIVE_SRC_MAIN_RESOURCES}/react4xp`; var DIR_PATH_RELATIVE_SRC_SITE = `${DIR_PATH_RELATIVE_SRC_MAIN_RESOURCES}/site`; var DIR_PATH_RELATIVE_BUILD_RESOURCES_MAIN = "build/resources/main"; var DIR_PATH_RELATIVE_BUILD_LIB_R4X = `${DIR_PATH_RELATIVE_BUILD_RESOURCES_MAIN}/lib/enonic/react4xp`; var DIR_PATH_RELATIVE_BUILD_ASSETS_R4X = `${DIR_PATH_RELATIVE_BUILD_RESOURCES_MAIN}/${R4X_TARGETSUBDIR}`; var GLOBALS_DEFAULT = { react: "React", "react-dom": "ReactDOM", "react-dom/server": "ReactDOMServer", "html-react-parser": "HTMLReactParser" // Adding it to globals to make sure we use server-side version of html-dom-parser dependency }; var FILE_NAME_R4X_CONFIG_JS = "react4xp.config.js"; // src/globals/generateTempES6SourceAndGetFilename.ts var import_fs = require("fs"); // src/util/isObject.ts var isObject = (value) => Object.prototype.toString.call(value).slice(8, -1) === "Object"; // src/util/isString.ts var isString = (value) => typeof value === "string" || value instanceof String; // src/globals/generateTempES6SourceAndGetFilename.ts function generateTempES6SourceAndGetFilename(globals, outputFileName) { if (typeof outputFileName !== "string" || (outputFileName || "").trim() === "") { console.warn(`${__filename} - Skipping generation of the globals chunk: The outputFileName parameter must be a non-empty string: ${JSON.stringify( outputFileName, null, 2 )}`); return null; } let globalsObj; if (isString(globals)) { globalsObj = JSON.parse(globals); } else if (isObject(globals)) { globalsObj = JSON.parse(JSON.stringify(globals)); } if (!globalsObj || !isObject(globalsObj) || //Array.isArray(globalsObj) || Object.keys(globalsObj).length < 1) { console.warn(`${__filename} - Skipping generation of the globals chunk: The globals parameter must be an object (or JSON-string object) with at least one entry: ${JSON.stringify( globalsObj, null, 2 )}`); return null; } let globalsImports = ""; let globalsExports = ""; Object.keys(globalsObj).forEach((key) => { globalsImports += `import ${globalsObj[key]} from '${key}'; `; }); if (globalsObj["react-dom"]) { globalsImports += `import * as ReactDOMClient from 'react-dom/client'; `; } globalsImports += `import {getPublicPath} from './index.js'; `; Object.keys(globalsObj).forEach((key) => { const globalName = globalsObj[key]; if (key === "react-dom" && globalName === "ReactDOM") { globalsExports += ` globalThis.${globalName} = Object.assign({}, ${globalName}, ReactDOMClient); `; } else { globalsExports += ` globalThis.${globalName} = ${globalName}; `; } }); globalsExports += ` if (typeof document !== "undefined") { globalThis.__R4XP_PUBLIC_PATH__ = getPublicPath("${process.env.R4X_APP_NAME}"); } `; const globalsES6 = `// AUTO-GENERATED by ${__filename} ${globalsImports} (function() { ${globalsExports}} )(); `; (0, import_fs.writeFileSync)(outputFileName, globalsES6); return outputFileName; } // src/util/makeVerboseLogger.ts var import_q_i = require("q-i"); var makeVerboseLogger = (VERBOSE) => VERBOSE ? (item, label, stringify = false) => { if (typeof item === "object") { if (label) { console.log(label + ":"); } (0, import_q_i.print)(item, { maxItems: Infinity }); } else if (stringify) { console.log((label ? label + " " : "") + "(" + typeof item + "): " + JSON.stringify(item)); } else { console.log((label ? label + ": " : "") + item); } } : () => { }; // src/util/webpackLogLevel.ts function webpackLogLevel(r4xBuildLogLevel = "LIFECYCLE" /* LIFECYCLE */) { switch (r4xBuildLogLevel) { case "QUIET" /* QUIET */: return "none" /* NONE */; // disable logging case "ERROR" /* ERROR */: return "error" /* ERROR */; // errors only case "WARN" /* WARN */: return "warn" /* WARN */; // errors and warnings only case "LIFECYCLE" /* LIFECYCLE */: return "info" /* INFO */; // errors, warnings, and info messages case "INFO" /* INFO */: return "log" /* LOG */; // errors, warnings, info messages, log messages, groups, clears. Collapsed groups are displayed in a collapsed state case "DEBUG" /* DEBUG */: return "verbose" /* VERBOSE */; // log everything except debug and trace default: console.warn(`Unknown log level '${r4xBuildLogLevel}' falling back to default log level 'info'`); return "info" /* INFO */; } } // src/webpack.config.globals.ts var import_filemanager_webpack_plugin = __toESM(require("filemanager-webpack-plugin")); var webpack_config_globals_default = () => { const R4X_DIR_PATH_ABSOLUTE_PROJECT = process.env.R4X_DIR_PATH_ABSOLUTE_PROJECT; if (!(0, import_path.isAbsolute)(R4X_DIR_PATH_ABSOLUTE_PROJECT)) { throw new Error(`System environment variable R4X_DIR_PATH_ABSOLUTE_PROJECT:${R4X_DIR_PATH_ABSOLUTE_PROJECT} not an absolute path!`); } const DIR_PATH_ABSOLUTE_BUILD_SYSTEM = (0, import_path.resolve)(__dirname, ".."); const DIR_PATH_ABSOLUTE_BUILD_ASSETS_R4X = (0, import_path.join)(R4X_DIR_PATH_ABSOLUTE_PROJECT, DIR_PATH_RELATIVE_BUILD_ASSETS_R4X); const WEBPACK_MODE = process.env.NODE_ENV || "production"; const DEVMODE = WEBPACK_MODE !== "production"; const LOG_LEVEL = webpackLogLevel(process.env.R4X_BUILD_LOG_LEVEL); const verboseLog = makeVerboseLogger([ "log" /* LOG */, "verbose" /* VERBOSE */ ].includes(LOG_LEVEL)); verboseLog(DIR_PATH_ABSOLUTE_BUILD_ASSETS_R4X, "DIR_PATH_ABSOLUTE_BUILD_ASSETS_R4X", 1); let GLOBALS = GLOBALS_DEFAULT; verboseLog(GLOBALS, "GLOBALS"); const FILE_PATH_ABSOLUTE_R4X_CONFIG_JS = (0, import_path.join)(R4X_DIR_PATH_ABSOLUTE_PROJECT, FILE_NAME_R4X_CONFIG_JS); try { const configJsonStats = (0, import_fs2.statSync)(FILE_PATH_ABSOLUTE_R4X_CONFIG_JS); if (configJsonStats.isFile()) { const config = require(FILE_PATH_ABSOLUTE_R4X_CONFIG_JS); if (config.globals) { GLOBALS = Object.assign(config.globals, GLOBALS); } } verboseLog(GLOBALS, "GLOBALS"); } catch (e) { console.info(`${FILE_PATH_ABSOLUTE_R4X_CONFIG_JS} not found.`); } const tempFileName = generateTempES6SourceAndGetFilename( GLOBALS, (0, import_path.join)(__dirname, "_AUTOGENERATED_tmp_global_.es6") ); const entry = tempFileName ? { globals: tempFileName } : {}; const plugins = tempFileName ? [ new import_filemanager_webpack_plugin.default({ events: { onStart: { mkdir: [ DIR_PATH_ABSOLUTE_BUILD_ASSETS_R4X // Chunks2json fails without this (when using npm explore) ] } } }), // // @ts-expect-error /*new CoreWebPlugin({ browsers: { chrome: "63", firefox: "57", edge: "18", opera: "57", safari: "12", ie: "11", } }),*/ new import_chunks_2_json_webpack_plugin.default({ outputDir: DIR_PATH_ABSOLUTE_BUILD_ASSETS_R4X, filename: GLOBALS_FILENAME }) ] : void 0; return { context: R4X_DIR_PATH_ABSOLUTE_PROJECT, // Used as default for resolve.roots devtool: DEVMODE ? false : "source-map", entry, mode: WEBPACK_MODE, module: { rules: [{ test: /\.((jt)sx?|(es6?))$/, // js, ts, jsx, tsx, es, es6 // I don't think we can exclude much, everything must be able to run: // * server-side (Nashorn/Graal-JS) and // * client-side (Browsers). //exclude: /node_modules/, // It takes time to transpile, if you know they don't need // transpilation to run in Enonic XP (Nashorn/Graal-JS) you may list // them here: exclude: [ /[\\/]node_modules[\\/]core-js/, // will cause errors if they are transpiled by Babel // /[\\/]node_modules[\\/]react[\\/]/, // TODO Perhaps react don't need to be transpiled // /[\\/]node_modules[\\/]react-dom[\\/]/, // TODO Perhaps react-dom don't need to be transpiled /[\\/]node_modules[\\/]webpack[\\/]buildin/ // will cause errors if they are transpiled by Babel ], use: [{ loader: "builtin:swc-loader", options: { jsc: { // https://swc.rs/docs/configuration/compilation#jscexternalhelpers // externalHelpers: true, parser: { dynamicImport: false, jsx: true, syntax: "typescript", tsx: true }, // target: 'es2015', transform: { react: { runtime: "automatic", development: DEVMODE, // $RefreshReg$ is not defined // refresh: DEVMODE, refresh: false } } }, minify: !DEVMODE, // module: { // type: 'commonjs' // }, sourceMaps: !DEVMODE } }] // use }] // rules }, // module optimization: { minimize: !DEVMODE, usedExports: !DEVMODE // Disable slow tree-shaking in dev mode }, output: { path: DIR_PATH_ABSOLUTE_BUILD_ASSETS_R4X, // <-- Sets the base url for plugins and other target dirs. filename: DEVMODE ? "[name].js" : "[name].[contenthash].js", environment: { arrowFunction: false, bigIntLiteral: false, const: false, destructuring: false, dynamicImport: false, forOf: false, module: false } }, // output performance: { hints: false }, plugins, resolve: { alias: { // Graalvm works with server-side version only! "html-dom-parser": [ (0, import_path.resolve)(R4X_DIR_PATH_ABSOLUTE_PROJECT, "node_modules/html-dom-parser/lib/server/html-to-dom.js"), (0, import_path.resolve)(DIR_PATH_ABSOLUTE_BUILD_SYSTEM, "node_modules/html-dom-parser/lib/server/html-to-dom.js") ] }, extensions: [".ts", ".tsx", ".es6", ".es", ".jsx", ".js", ".json"], modules: [ // Tell webpack what directories should be searched when resolving // modules. // Absolute and relative paths can both be used, but be aware that they // will behave a bit differently. // A relative path will be scanned similarly to how Node scans for // node_modules, by looking through the current directory as well as its // ancestors (i.e. ./node_modules, ../node_modules, and on). // With an absolute path, it will only search in the given directory. // To resolve node_modules installed under the app (0, import_path.resolve)(R4X_DIR_PATH_ABSOLUTE_PROJECT, "node_modules"), // To resolve node_modules installed under the build system (0, import_path.resolve)(DIR_PATH_ABSOLUTE_BUILD_SYSTEM, "node_modules") //'node_modules' ] /*roots: [ // Works, but maybe modules is more specific // A list of directories where requests of server-relative URLs // (starting with '/') are resolved, defaults to context configuration // option. On non-Windows systems these requests are resolved as an // absolute path first. R4X_DIR_PATH_ABSOLUTE_PROJECT, // same as context DIR_PATH_ABSOLUTE_BUILD_SYSTEM ],*/ }, // resolve stats: { colors: true, hash: false, logging: LOG_LEVEL, modules: false, moduleTrace: false, timings: false, version: false } // stats }; };