From 52040af6cc547852e2e26109e96a015f0797db23 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Tue, 12 Nov 2024 12:12:25 +0300 Subject: [PATCH 01/19] added new fat-html=3 mode with async chunks and shadowing scripts --- build/monic/attach-component-dependencies.js | 2 +- build/monic/dynamic-component-import.js | 7 +- build/webpack/module/rules/ess.js | 19 ++- build/webpack/plugins.js | 9 +- .../plugins/async-chunks-plugin/README.md | 11 ++ .../plugins/async-chunks-plugin/index.js | 109 ++++++++++++++++++ config/default.js | 20 +++- .../super/i-static-page/i-static-page.html.ss | 1 + .../i-static-page/modules/ss-helpers/page.js | 31 +++++ 9 files changed, 198 insertions(+), 11 deletions(-) create mode 100644 build/webpack/plugins/async-chunks-plugin/README.md create mode 100644 build/webpack/plugins/async-chunks-plugin/index.js diff --git a/build/monic/attach-component-dependencies.js b/build/monic/attach-component-dependencies.js index 24e1550f60..66ce116543 100644 --- a/build/monic/attach-component-dependencies.js +++ b/build/monic/attach-component-dependencies.js @@ -27,7 +27,7 @@ const * @returns {Promise} */ module.exports = async function attachComponentDependencies(str, filePath) { - if (webpack.fatHTML()) { + if (webpack.fatHTML() !== 3) { return str; } diff --git a/build/monic/dynamic-component-import.js b/build/monic/dynamic-component-import.js index 5bc18ae3c8..d2d67344d7 100644 --- a/build/monic/dynamic-component-import.js +++ b/build/monic/dynamic-component-import.js @@ -99,9 +99,12 @@ module.exports = async function dynamicComponentImportReplacer(str) { imports.push(decl); } - // In FatHTML, we do not include dynamically loaded CSS because it leads to duplication + // In FatHTML (excepting 3rd mode), we do not include dynamically loaded CSS because it leads to duplication // of the CSS and its associated assets - if (!fatHTML) { + + const isThirdFatHTMLMode = fatHTML === 3; + + if (isThirdFatHTMLMode) { const stylPath = `${fullPath}.styl`; diff --git a/build/webpack/module/rules/ess.js b/build/webpack/module/rules/ess.js index ce079f8065..4cb98b6e89 100644 --- a/build/webpack/module/rules/ess.js +++ b/build/webpack/module/rules/ess.js @@ -25,7 +25,9 @@ const * @returns {Promise} */ module.exports = async function essRules() { - const g = await projectGraph; + const + g = await projectGraph, + isThirdFatHTMLMode = config.webpack.fatHtml() === 3 ; return { test: /\.ess$/, @@ -37,12 +39,17 @@ module.exports = async function essRules() { } }, - 'extract-loader', + ...(!isThirdFatHTMLMode ? + [ + 'extract-loader', - { - loader: 'html-loader', - options: config.html() - }, + { + loader: 'html-loader', + options: config.html() + }, + ] : + [] + ), { loader: 'monic-loader', diff --git a/build/webpack/plugins.js b/build/webpack/plugins.js index 5e2972aebd..16dc35e7f3 100644 --- a/build/webpack/plugins.js +++ b/build/webpack/plugins.js @@ -33,6 +33,7 @@ module.exports = async function plugins({name}) { IgnoreInvalidWarningsPlugin = include('build/webpack/plugins/ignore-invalid-warnings'), I18NGeneratorPlugin = include('build/webpack/plugins/i18n-plugin'), InvalidateExternalCachePlugin = include('build/webpack/plugins/invalidate-external-cache'), + AsyncChunksPlugin = include('build/webpack/plugins/async-chunks-plugin'), StatoscopeWebpackPlugin = require('@statoscope/webpack-plugin').default; const plugins = new Map([ @@ -67,11 +68,17 @@ module.exports = async function plugins({name}) { plugins.set('progress-plugin', createProgressPlugin(name)); } - if (config.webpack.fatHTML() || config.webpack.storybook() || config.webpack.ssr) { + const isThirdFatHTMLMode = config.webpack.fatHTML() === 3; + + if ((config.webpack.fatHTML() && !isThirdFatHTMLMode) || config.webpack.storybook() || config.webpack.ssr) { plugins.set('limit-chunk-count-plugin', new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })); } + if (isThirdFatHTMLMode) { + plugins.set('async-chunk-plugin', new AsyncChunksPlugin()); + } + return plugins; }; diff --git a/build/webpack/plugins/async-chunks-plugin/README.md b/build/webpack/plugins/async-chunks-plugin/README.md new file mode 100644 index 0000000000..777ac4b3b5 --- /dev/null +++ b/build/webpack/plugins/async-chunks-plugin/README.md @@ -0,0 +1,11 @@ +# build/webpack/plugins/async-chunks-plugin + +This module provides a plugin that gathers information about asynchronous chunks and modifies the webpack runtime to load asynchronous modules from shadow storage in fat-html. + +## Gathering Information + +During the initial phase, the plugin gathers information about all emitted asynchronous chunks. This information is stored in a JSON file within the output directory and later used to inline those scripts into the HTML using a special template tag. + +## Patching the Webpack Runtime + +The plugin replaces the standard RuntimeGlobals.loadScript script. The new script attempts to locate a template tag with the ID of the chunk name and adds the located script to the page. If there is no such template with the script, the standard method is called to load the chunk from the network. diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js new file mode 100644 index 0000000000..3df754771f --- /dev/null +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -0,0 +1,109 @@ +use strict'; + +/*! + * V4Fire Client Core + * https://github.com/V4Fire/Client + * + * Released under the MIT license + * https://github.com/V4Fire/Client/blob/master/LICENSE + */ + +const fs = require('fs'); +const path = require('path'); +const RuntimeModule = require('webpack/lib/RuntimeModule'); +const RuntimeGlobals = require('webpack/lib/RuntimeGlobals'); + +const {webpack} = require('@config/config'); + +class AsyncPlugRuntimeModule extends RuntimeModule { + constructor() { + super('async chunk loader for fat-html', RuntimeModule.STAGE_ATTACH); + } + + generate() { + return `var loadScript = ${RuntimeGlobals.loadScript}; +function loadScriptReplacement(path, cb, chunk, id) { + var tpl = document.getElementById(id); + if (tpl && tpl.content) { + document.body.appendChild(tpl.content.cloneNode(true)); + cb(); + } else { + loadScript(path, cb, chunk, id); + } +} +${RuntimeGlobals.loadScript} = loadScriptReplacement`; + } +} + +class Index { + apply(compiler) { + compiler.hooks.thisCompilation.tap( + 'AsyncChunksPlugin', + (compilation) => { + const onceForChunkSet = new WeakSet(); + + compilation.hooks.runtimeRequirementInTree + .for(RuntimeGlobals.ensureChunkHandlers) + .tap('AsyncChunksPlugin', (chunk, set) => { + if (onceForChunkSet.has(chunk)) { + return; + } + + onceForChunkSet.add(chunk); + + const runtimeModule = new AsyncPlugRuntimeModule(); + set.add(RuntimeGlobals.loadScript); + compilation.addRuntimeModule(chunk, runtimeModule); + }); + } + ); + + compiler.hooks.emit.tapAsync('AsyncChunksPlugin', (compilation, callback) => { + const asyncChunks = []; + if (compilation.name !== 'runtime') { + callback(); + return; + } + + compilation.chunks.forEach((chunk) => { + if (chunk.canBeInitial()) { + return; + } + + asyncChunks.push({ + id: chunk.id, + files: chunk.files.map((filename) => filename) + }); + }); + + const outputPath = path.join(compiler.options.output.path, webpack.asyncAssetsJSON()); + + fs.writeFile(outputPath, JSON.stringify(asyncChunks, null, 2), (err) => { + if (err) { + compilation.errors.push(new Error(`Error write async chunks list to ${outputPath}`)); + } + + callback(); + }); + }); + + compiler.hooks.done.tapAsync('AsyncChunksPlugin', (stat, callback) => { + if (stat.compilation.name === 'html') { + const + filePath = path.join(compiler.options.output.path, webpack.asyncAssetsJSON()), + fileContent = fs.readFileSync(filePath, 'utf-8'), + asyncChunks = JSON.parse(fileContent); + + asyncChunks.forEach((chunk) => { + chunk.files.forEach((file) => { + fs.rmSync(path.join(compiler.options.output.path, file)); + }); + }); + } + + callback(); + }); + } +} + +module.exports = Index; \ No newline at end of file diff --git a/config/default.js b/config/default.js index ff24a7962d..4da17df19f 100644 --- a/config/default.js +++ b/config/default.js @@ -434,7 +434,8 @@ module.exports = config.createConfig({dirs: [__dirname, 'client']}, { * Returns * 1. `1` if all resources from the build should be embedded in HTML files; * 2. `2` if all scripts and links from the build should be embedded in HTML files; - * 3. `0` if resources from the build should not be embedded in HTML files. + * 3. `3` if some scripts and components should be embedded in shadow HTML [TBD] + * 4. `0` if resources from the build should not be embedded in HTML files. * * @cli fat-html * @env FAT_HTML @@ -825,6 +826,23 @@ module.exports = config.createConfig({dirs: [__dirname, 'client']}, { return path.changeExt(this.assetsJSON(), '.js'); }, + /** + * Returns the path to the generated async assets chunks list within the output directory. + * It contains an array of async chunks and their file names to inline them into fat-html. + * ... + * [ + * { + * id: 'chunk_id', + * files: ['filename.ext'] + * } + * ] + * + * @return {string} + */ + asyncAssetsJSON() { + return 'async-chunks-to-inline.json'; + } + /** * Returns options for displaying webpack build progress * diff --git a/src/components/super/i-static-page/i-static-page.html.ss b/src/components/super/i-static-page/i-static-page.html.ss index 6b16e54636..4720abcf2c 100644 --- a/src/components/super/i-static-page/i-static-page.html.ss +++ b/src/components/super/i-static-page/i-static-page.html.ss @@ -140,6 +140,7 @@ `${result}`, ''); + } + + return `
${asyncChunks.reduce((result, chunk) => `${result}`, '')}
`; + + } catch (e) { + return ''; + } +} + exports.getPageStyleDepsDecl = getPageStyleDepsDecl; /** From c5bffd4c91ee83796a5ce8c664483807bee5f3e2 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Tue, 12 Nov 2024 12:17:52 +0300 Subject: [PATCH 02/19] fixed condition mistake --- build/monic/attach-component-dependencies.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/monic/attach-component-dependencies.js b/build/monic/attach-component-dependencies.js index 66ce116543..f278b25895 100644 --- a/build/monic/attach-component-dependencies.js +++ b/build/monic/attach-component-dependencies.js @@ -27,7 +27,7 @@ const * @returns {Promise} */ module.exports = async function attachComponentDependencies(str, filePath) { - if (webpack.fatHTML() !== 3) { + if (webpack.fatHTML() === 3) { return str; } From 76036fabb2b6c864f935617d55fae7d982e89d3e Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Tue, 12 Nov 2024 12:22:40 +0300 Subject: [PATCH 03/19] fix: added comma --- config/default.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/config/default.js b/config/default.js index 4da17df19f..735356f712 100644 --- a/config/default.js +++ b/config/default.js @@ -434,7 +434,7 @@ module.exports = config.createConfig({dirs: [__dirname, 'client']}, { * Returns * 1. `1` if all resources from the build should be embedded in HTML files; * 2. `2` if all scripts and links from the build should be embedded in HTML files; - * 3. `3` if some scripts and components should be embedded in shadow HTML [TBD] + * 3. `3` if some scripts and components should be embedded in shadow HTML [TBD]; * 4. `0` if resources from the build should not be embedded in HTML files. * * @cli fat-html @@ -841,7 +841,7 @@ module.exports = config.createConfig({dirs: [__dirname, 'client']}, { */ asyncAssetsJSON() { return 'async-chunks-to-inline.json'; - } + }, /** * Returns options for displaying webpack build progress From 0a215e882ce4fbff4ec07cb2c5dc0b474d7ecb2b Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Tue, 12 Nov 2024 12:26:35 +0300 Subject: [PATCH 04/19] eslint: fixed issues --- build/webpack/module/rules/ess.js | 4 ++-- build/webpack/plugins/async-chunks-plugin/index.js | 8 ++++---- config/default.js | 2 +- .../super/i-static-page/modules/ss-helpers/page.js | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/build/webpack/module/rules/ess.js b/build/webpack/module/rules/ess.js index 4cb98b6e89..0e83dd08ac 100644 --- a/build/webpack/module/rules/ess.js +++ b/build/webpack/module/rules/ess.js @@ -27,7 +27,7 @@ const module.exports = async function essRules() { const g = await projectGraph, - isThirdFatHTMLMode = config.webpack.fatHtml() === 3 ; + isThirdFatHTMLMode = config.webpack.fatHtml() === 3; return { test: /\.ess$/, @@ -46,7 +46,7 @@ module.exports = async function essRules() { { loader: 'html-loader', options: config.html() - }, + } ] : [] ), diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index 3df754771f..38ce7312a8 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -1,5 +1,3 @@ -use strict'; - /*! * V4Fire Client Core * https://github.com/V4Fire/Client @@ -8,6 +6,8 @@ use strict'; * https://github.com/V4Fire/Client/blob/master/LICENSE */ +'use strict'; + const fs = require('fs'); const path = require('path'); const RuntimeModule = require('webpack/lib/RuntimeModule'); @@ -54,7 +54,7 @@ class Index { const runtimeModule = new AsyncPlugRuntimeModule(); set.add(RuntimeGlobals.loadScript); compilation.addRuntimeModule(chunk, runtimeModule); - }); + }); } ); @@ -106,4 +106,4 @@ class Index { } } -module.exports = Index; \ No newline at end of file +module.exports = Index; diff --git a/config/default.js b/config/default.js index 735356f712..136ca8edb7 100644 --- a/config/default.js +++ b/config/default.js @@ -837,7 +837,7 @@ module.exports = config.createConfig({dirs: [__dirname, 'client']}, { * } * ] * - * @return {string} + * @returns {string} */ asyncAssetsJSON() { return 'async-chunks-to-inline.json'; diff --git a/src/components/super/i-static-page/modules/ss-helpers/page.js b/src/components/super/i-static-page/modules/ss-helpers/page.js index 3bf0278f24..8ae6875e23 100644 --- a/src/components/super/i-static-page/modules/ss-helpers/page.js +++ b/src/components/super/i-static-page/modules/ss-helpers/page.js @@ -97,8 +97,8 @@ function getPageAsyncScripts() { } return `
${asyncChunks.reduce((result, chunk) => `${result}`, '')}
`; + chunk.files.map((fileName) => `include('${src.clientOutput(fileName)}');\n`).join() + }`, '')}`; } catch (e) { return ''; From 43e595b6129e55d8c529a6c2687b0116fa285ef6 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Tue, 12 Nov 2024 12:38:31 +0300 Subject: [PATCH 05/19] fix: function name to invoke this --- build/webpack/module/rules/ess.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/webpack/module/rules/ess.js b/build/webpack/module/rules/ess.js index 0e83dd08ac..7f3b12de0b 100644 --- a/build/webpack/module/rules/ess.js +++ b/build/webpack/module/rules/ess.js @@ -27,7 +27,7 @@ const module.exports = async function essRules() { const g = await projectGraph, - isThirdFatHTMLMode = config.webpack.fatHtml() === 3; + isThirdFatHTMLMode = config.webpack.fatHTML() === 3; return { test: /\.ess$/, From 3faf4c8f1585069d0020b0880a65bfd63ebbc374 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Tue, 12 Nov 2024 15:10:13 +0300 Subject: [PATCH 06/19] fixed conditions for fatHTML modes --- build/monic/attach-component-dependencies.js | 2 +- build/monic/dynamic-component-import.js | 3 +-- build/webpack/module/rules/ts.js | 4 ++-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/build/monic/attach-component-dependencies.js b/build/monic/attach-component-dependencies.js index f278b25895..29f3cae3c4 100644 --- a/build/monic/attach-component-dependencies.js +++ b/build/monic/attach-component-dependencies.js @@ -27,7 +27,7 @@ const * @returns {Promise} */ module.exports = async function attachComponentDependencies(str, filePath) { - if (webpack.fatHTML() === 3) { + if (webpack.fatHTML() && webpack.fatHTML() !== 3) { return str; } diff --git a/build/monic/dynamic-component-import.js b/build/monic/dynamic-component-import.js index d2d67344d7..61e21bb1ef 100644 --- a/build/monic/dynamic-component-import.js +++ b/build/monic/dynamic-component-import.js @@ -101,10 +101,9 @@ module.exports = async function dynamicComponentImportReplacer(str) { // In FatHTML (excepting 3rd mode), we do not include dynamically loaded CSS because it leads to duplication // of the CSS and its associated assets - const isThirdFatHTMLMode = fatHTML === 3; - if (isThirdFatHTMLMode) { + if (isThirdFatHTMLMode || !fatHTML) { const stylPath = `${fullPath}.styl`; diff --git a/build/webpack/module/rules/ts.js b/build/webpack/module/rules/ts.js index 7d3c7f4617..d83f1bac88 100644 --- a/build/webpack/module/rules/ts.js +++ b/build/webpack/module/rules/ts.js @@ -65,8 +65,8 @@ module.exports = function tsRules() { loader: 'monic-loader', options: inherit(monic.typescript, { replacers: [].concat( - fatHTML ? - [] : + fatHTML && fatHTML !== 3 ? + [] : include('build/monic/attach-component-dependencies'), [ From ea27129f67dff99fb235d5b8ddc3cbd9afb137bb Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Tue, 12 Nov 2024 15:18:46 +0300 Subject: [PATCH 07/19] fix: eslint issues --- build/webpack/module/rules/ts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/webpack/module/rules/ts.js b/build/webpack/module/rules/ts.js index d83f1bac88..ec04179402 100644 --- a/build/webpack/module/rules/ts.js +++ b/build/webpack/module/rules/ts.js @@ -66,7 +66,7 @@ module.exports = function tsRules() { options: inherit(monic.typescript, { replacers: [].concat( fatHTML && fatHTML !== 3 ? - [] : + [] : include('build/monic/attach-component-dependencies'), [ From b6fdeb8c584c32fd9e1fadb543ccffbd91cf7bb2 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Thu, 14 Nov 2024 15:21:44 +0300 Subject: [PATCH 08/19] put the getPageAsyncScript down --- src/components/super/i-static-page/i-static-page.html.ss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/super/i-static-page/i-static-page.html.ss b/src/components/super/i-static-page/i-static-page.html.ss index 4720abcf2c..d9b5ca5822 100644 --- a/src/components/super/i-static-page/i-static-page.html.ss +++ b/src/components/super/i-static-page/i-static-page.html.ss @@ -140,7 +140,6 @@ Date: Thu, 14 Nov 2024 21:07:06 +0300 Subject: [PATCH 09/19] use script with type 'text/template' instead template --- build/webpack/plugins/async-chunks-plugin/index.js | 11 ++++++++--- .../super/i-static-page/modules/ss-helpers/page.js | 8 ++++---- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index 38ce7312a8..5ca6442c3a 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -23,10 +23,15 @@ class AsyncPlugRuntimeModule extends RuntimeModule { generate() { return `var loadScript = ${RuntimeGlobals.loadScript}; function loadScriptReplacement(path, cb, chunk, id) { - var tpl = document.getElementById(id); - if (tpl && tpl.content) { - document.body.appendChild(tpl.content.cloneNode(true)); + if (document.getElementById(id) != null) { + const + tplText = document.getElementById(id).textContent, + tempDiv = document.createElement('div'); + + tempDiv.innerHTML = tplText; + document.body.appendChild(tempDiv.firstElementChild); cb(); + } else { loadScript(path, cb, chunk, id); } diff --git a/src/components/super/i-static-page/modules/ss-helpers/page.js b/src/components/super/i-static-page/modules/ss-helpers/page.js index 8ae6875e23..e75725f6b2 100644 --- a/src/components/super/i-static-page/modules/ss-helpers/page.js +++ b/src/components/super/i-static-page/modules/ss-helpers/page.js @@ -91,14 +91,14 @@ function getPageAsyncScripts() { asyncChunks = JSON.parse(fileContent); if (webpack.mode() === 'production') { - return asyncChunks.reduce((result, chunk) => `${result}`, ''); + }`, ''); } - return `
${asyncChunks.reduce((result, chunk) => `${result}`, '')}
`; + }`, '')}`; } catch (e) { return ''; From 21e4f0254a15cb474f758fe022ac295378f3687a Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Thu, 14 Nov 2024 22:01:27 +0300 Subject: [PATCH 10/19] revert last changes --- build/webpack/plugins/async-chunks-plugin/index.js | 11 +++-------- .../super/i-static-page/modules/ss-helpers/page.js | 10 +++++----- 2 files changed, 8 insertions(+), 13 deletions(-) diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index 5ca6442c3a..38ce7312a8 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -23,15 +23,10 @@ class AsyncPlugRuntimeModule extends RuntimeModule { generate() { return `var loadScript = ${RuntimeGlobals.loadScript}; function loadScriptReplacement(path, cb, chunk, id) { - if (document.getElementById(id) != null) { - const - tplText = document.getElementById(id).textContent, - tempDiv = document.createElement('div'); - - tempDiv.innerHTML = tplText; - document.body.appendChild(tempDiv.firstElementChild); + var tpl = document.getElementById(id); + if (tpl && tpl.content) { + document.body.appendChild(tpl.content.cloneNode(true)); cb(); - } else { loadScript(path, cb, chunk, id); } diff --git a/src/components/super/i-static-page/modules/ss-helpers/page.js b/src/components/super/i-static-page/modules/ss-helpers/page.js index e75725f6b2..3bf0278f24 100644 --- a/src/components/super/i-static-page/modules/ss-helpers/page.js +++ b/src/components/super/i-static-page/modules/ss-helpers/page.js @@ -91,14 +91,14 @@ function getPageAsyncScripts() { asyncChunks = JSON.parse(fileContent); if (webpack.mode() === 'production') { - return asyncChunks.reduce((result, chunk) => `${result}`, ''); + }`, ''); } - return `
${asyncChunks.reduce((result, chunk) => `${result}`, '')}
`; + return `
${asyncChunks.reduce((result, chunk) => `${result}`, '')}
`; } catch (e) { return ''; From ff86d6a550916812dd3264b1f5451247c719287c Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Thu, 14 Nov 2024 23:41:39 +0300 Subject: [PATCH 11/19] fixed condition when async-chunks-plugin applies --- build/webpack/plugins.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/webpack/plugins.js b/build/webpack/plugins.js index 16dc35e7f3..09d840cc03 100644 --- a/build/webpack/plugins.js +++ b/build/webpack/plugins.js @@ -70,7 +70,7 @@ module.exports = async function plugins({name}) { const isThirdFatHTMLMode = config.webpack.fatHTML() === 3; - if ((config.webpack.fatHTML() && !isThirdFatHTMLMode) || config.webpack.storybook() || config.webpack.ssr) { + if ((config.webpack.fatHTML() || config.webpack.storybook() || config.webpack.ssr) && !isThirdFatHTMLMode) { plugins.set('limit-chunk-count-plugin', new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 })); From f73b8e3b0f3433c10d2586bb379fad013851c0fa Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Fri, 15 Nov 2024 18:53:06 +0300 Subject: [PATCH 12/19] pass script as text --- .../plugins/async-chunks-plugin/index.js | 9 ++++++--- .../super/i-static-page/i-static-page.html.ss | 18 +++++++++--------- .../i-static-page/modules/ss-helpers/page.js | 8 ++++---- 3 files changed, 19 insertions(+), 16 deletions(-) diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index 38ce7312a8..fc577651aa 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -23,9 +23,12 @@ class AsyncPlugRuntimeModule extends RuntimeModule { generate() { return `var loadScript = ${RuntimeGlobals.loadScript}; function loadScriptReplacement(path, cb, chunk, id) { - var tpl = document.getElementById(id); - if (tpl && tpl.content) { - document.body.appendChild(tpl.content.cloneNode(true)); + if (document.getElementById(id) != null) { + const + tplText = document.getElementById(id).innerText, + tempDiv = document.createElement('div'); + tempDiv.innerHTML = tplText; + document.body.appendChild(tempDiv.firstElementChild); cb(); } else { loadScript(path, cb, chunk, id); diff --git a/src/components/super/i-static-page/i-static-page.html.ss b/src/components/super/i-static-page/i-static-page.html.ss index d9b5ca5822..fd52fb4b24 100644 --- a/src/components/super/i-static-page/i-static-page.html.ss +++ b/src/components/super/i-static-page/i-static-page.html.ss @@ -141,15 +141,6 @@ - block headScripts += await h.loadLibs(deps.headScripts, {assets, wrap: inlineDepsDeclarations, js: inlineDepsDeclarations}) - += h.getScriptDeclByName('std', {assets, optional: true, wrap: inlineDepsDeclarations, js: inlineDepsDeclarations}) - += await h.loadLibs(deps.scripts, {assets, wrap: inlineDepsDeclarations, js: inlineDepsDeclarations}) - - += h.getScriptDeclByName('vendor', {assets, optional: true, wrap: inlineDepsDeclarations, js: inlineDepsDeclarations}) - += h.getScriptDeclByName('index-core', {assets, optional: true, wrap: inlineDepsDeclarations, js: inlineDepsDeclarations}) - - += h.getPageScriptDepsDecl(ownDeps, {assets, wrap: inlineDepsDeclarations, js: inlineDepsDeclarations}) - - += h.getPageAsyncScripts() < body ${rootAttrs|!html} `${result}`, ''); + }`, ''); } - return `
${asyncChunks.reduce((result, chunk) => `${result}`, '')}
`; + }`, '')}`; } catch (e) { return ''; From b246d0c07cb0f79cc84f4d6e644e7f58547be235 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Sat, 16 Nov 2024 00:20:59 +0300 Subject: [PATCH 13/19] use noframes tag for storing shadow scripts --- .../webpack/plugins/async-chunks-plugin/index.js | 15 ++++++++++----- .../i-static-page/modules/ss-helpers/page.js | 10 ++-------- 2 files changed, 12 insertions(+), 13 deletions(-) diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index fc577651aa..aaed8ad650 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -23,12 +23,16 @@ class AsyncPlugRuntimeModule extends RuntimeModule { generate() { return `var loadScript = ${RuntimeGlobals.loadScript}; function loadScriptReplacement(path, cb, chunk, id) { - if (document.getElementById(id) != null) { + const tpl = document.getElementById(id); + + if (tpl != null) { const - tplText = document.getElementById(id).innerText, - tempDiv = document.createElement('div'); - tempDiv.innerHTML = tplText; - document.body.appendChild(tempDiv.firstElementChild); + js = new Blob([tpl.textContent], {type: 'text/javascript'}), + src = URL.createObjectURL(js), + script = document.createElement('script'); + + script.src = src; + document.body.appendChild(script); cb(); } else { loadScript(path, cb, chunk, id); @@ -40,6 +44,7 @@ ${RuntimeGlobals.loadScript} = loadScriptReplacement`; class Index { apply(compiler) { + debugger; compiler.hooks.thisCompilation.tap( 'AsyncChunksPlugin', (compilation) => { diff --git a/src/components/super/i-static-page/modules/ss-helpers/page.js b/src/components/super/i-static-page/modules/ss-helpers/page.js index 0cdbcf1782..bee37105ae 100644 --- a/src/components/super/i-static-page/modules/ss-helpers/page.js +++ b/src/components/super/i-static-page/modules/ss-helpers/page.js @@ -90,15 +90,9 @@ function getPageAsyncScripts() { fileContent = fs.readFileSync(filePath, 'utf-8'), asyncChunks = JSON.parse(fileContent); - if (webpack.mode() === 'production') { - return asyncChunks.reduce((result, chunk) => `${result}`, ''); - } - - return `
${asyncChunks.reduce((result, chunk) => `${result}`, '')}
`; + }`, '')}`; } catch (e) { return ''; From 6c948fbb8515c6f0643f8ad9b202909b39470e38 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Sun, 17 Nov 2024 00:39:32 +0300 Subject: [PATCH 14/19] comment: removing modules after build --- build/webpack/plugins/async-chunks-plugin/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index aaed8ad650..0135b43bac 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -104,7 +104,7 @@ class Index { asyncChunks.forEach((chunk) => { chunk.files.forEach((file) => { - fs.rmSync(path.join(compiler.options.output.path, file)); + //fs.rmSync(path.join(compiler.options.output.path, file)); }); }); } From 13f91de792626aaeaeee644e3cd2adc9eeca6ff8 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Mon, 18 Nov 2024 12:01:35 +0300 Subject: [PATCH 15/19] inserrt scripts into noframess withour frameset --- build/webpack/plugins/async-chunks-plugin/index.js | 2 +- src/components/super/i-static-page/modules/ss-helpers/page.js | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index 0135b43bac..aaed8ad650 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -104,7 +104,7 @@ class Index { asyncChunks.forEach((chunk) => { chunk.files.forEach((file) => { - //fs.rmSync(path.join(compiler.options.output.path, file)); + fs.rmSync(path.join(compiler.options.output.path, file)); }); }); } diff --git a/src/components/super/i-static-page/modules/ss-helpers/page.js b/src/components/super/i-static-page/modules/ss-helpers/page.js index bee37105ae..79a6b19105 100644 --- a/src/components/super/i-static-page/modules/ss-helpers/page.js +++ b/src/components/super/i-static-page/modules/ss-helpers/page.js @@ -90,9 +90,9 @@ function getPageAsyncScripts() { fileContent = fs.readFileSync(filePath, 'utf-8'), asyncChunks = JSON.parse(fileContent); - return `${asyncChunks.reduce((result, chunk) => `${result}${ + return `${asyncChunks.reduce((result, chunk) => `${result}<noframes id="${chunk.id}">${ chunk.files.map((fileName) => `include('${src.clientOutput(fileName)}');\n`).join() - }`, '')}`; + }`, '')}`; } catch (e) { return ''; From 0255b4fe4ca586e516816e74f5686fe3819c2511 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Tue, 19 Nov 2024 16:33:17 +0300 Subject: [PATCH 16/19] fix eslint issues; remove handling done hook in async-chunks-plugin --- .../plugins/async-chunks-plugin/index.js | 17 ----------------- .../i-static-page/modules/ss-helpers/page.js | 4 ++-- 2 files changed, 2 insertions(+), 19 deletions(-) diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index aaed8ad650..87f1cdf8ac 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -94,23 +94,6 @@ class Index { callback(); }); }); - - compiler.hooks.done.tapAsync('AsyncChunksPlugin', (stat, callback) => { - if (stat.compilation.name === 'html') { - const - filePath = path.join(compiler.options.output.path, webpack.asyncAssetsJSON()), - fileContent = fs.readFileSync(filePath, 'utf-8'), - asyncChunks = JSON.parse(fileContent); - - asyncChunks.forEach((chunk) => { - chunk.files.forEach((file) => { - fs.rmSync(path.join(compiler.options.output.path, file)); - }); - }); - } - - callback(); - }); } } diff --git a/src/components/super/i-static-page/modules/ss-helpers/page.js b/src/components/super/i-static-page/modules/ss-helpers/page.js index 79a6b19105..9c7d3d32ed 100644 --- a/src/components/super/i-static-page/modules/ss-helpers/page.js +++ b/src/components/super/i-static-page/modules/ss-helpers/page.js @@ -91,8 +91,8 @@ function getPageAsyncScripts() { asyncChunks = JSON.parse(fileContent); return `${asyncChunks.reduce((result, chunk) => `${result}${ - chunk.files.map((fileName) => `include('${src.clientOutput(fileName)}');\n`).join() - }`, '')}`; + chunk.files.map((fileName) => `include('${src.clientOutput(fileName)}');\n`).join() + }`, '')}`; } catch (e) { return ''; From e3b0f916ae3a34017a8c5b62744018c58cdf42ae Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Wed, 20 Nov 2024 00:55:03 +0300 Subject: [PATCH 17/19] changed order of scripts --- .../plugins/async-chunks-plugin/index.js | 17 +++++++++++++++++ .../super/i-static-page/i-static-page.html.ss | 2 +- .../i-static-page/modules/ss-helpers/page.js | 4 ++-- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index 87f1cdf8ac..aaed8ad650 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -94,6 +94,23 @@ class Index { callback(); }); }); + + compiler.hooks.done.tapAsync('AsyncChunksPlugin', (stat, callback) => { + if (stat.compilation.name === 'html') { + const + filePath = path.join(compiler.options.output.path, webpack.asyncAssetsJSON()), + fileContent = fs.readFileSync(filePath, 'utf-8'), + asyncChunks = JSON.parse(fileContent); + + asyncChunks.forEach((chunk) => { + chunk.files.forEach((file) => { + fs.rmSync(path.join(compiler.options.output.path, file)); + }); + }); + } + + callback(); + }); } } diff --git a/src/components/super/i-static-page/i-static-page.html.ss b/src/components/super/i-static-page/i-static-page.html.ss index fd52fb4b24..e8e93c237a 100644 --- a/src/components/super/i-static-page/i-static-page.html.ss +++ b/src/components/super/i-static-page/i-static-page.html.ss @@ -140,6 +140,7 @@ `${result}${ + return `${asyncChunks.reduce((result, chunk) => `${result}<script id="${chunk.id}">${ chunk.files.map((fileName) => `include('${src.clientOutput(fileName)}');\n`).join() - }`, '')}`; + }`, '')}`; } catch (e) { return ''; From 78a11996700641343aba0d3bcc1ddf7b070ee465 Mon Sep 17 00:00:00 2001 From: Dzmitry Yahorau Date: Mon, 25 Nov 2024 14:29:16 +0300 Subject: [PATCH 18/19] changes comparing to fat-html=3' --- build/monic/attach-component-dependencies.js | 2 +- build/monic/dynamic-component-import.js | 2 +- build/webpack/module/rules/ess.js | 2 +- build/webpack/module/rules/ts.js | 2 +- build/webpack/plugins.js | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/build/monic/attach-component-dependencies.js b/build/monic/attach-component-dependencies.js index 29f3cae3c4..daf31954f6 100644 --- a/build/monic/attach-component-dependencies.js +++ b/build/monic/attach-component-dependencies.js @@ -27,7 +27,7 @@ const * @returns {Promise} */ module.exports = async function attachComponentDependencies(str, filePath) { - if (webpack.fatHTML() && webpack.fatHTML() !== 3) { + if (webpack.fatHTML() && webpack.fatHTML() != 3) { return str; } diff --git a/build/monic/dynamic-component-import.js b/build/monic/dynamic-component-import.js index 61e21bb1ef..2294fa1106 100644 --- a/build/monic/dynamic-component-import.js +++ b/build/monic/dynamic-component-import.js @@ -101,7 +101,7 @@ module.exports = async function dynamicComponentImportReplacer(str) { // In FatHTML (excepting 3rd mode), we do not include dynamically loaded CSS because it leads to duplication // of the CSS and its associated assets - const isThirdFatHTMLMode = fatHTML === 3; + const isThirdFatHTMLMode = fatHTML == 3; if (isThirdFatHTMLMode || !fatHTML) { const diff --git a/build/webpack/module/rules/ess.js b/build/webpack/module/rules/ess.js index 7f3b12de0b..c6db197ebc 100644 --- a/build/webpack/module/rules/ess.js +++ b/build/webpack/module/rules/ess.js @@ -27,7 +27,7 @@ const module.exports = async function essRules() { const g = await projectGraph, - isThirdFatHTMLMode = config.webpack.fatHTML() === 3; + isThirdFatHTMLMode = config.webpack.fatHTML() == 3; return { test: /\.ess$/, diff --git a/build/webpack/module/rules/ts.js b/build/webpack/module/rules/ts.js index ec04179402..bf4cca5523 100644 --- a/build/webpack/module/rules/ts.js +++ b/build/webpack/module/rules/ts.js @@ -65,7 +65,7 @@ module.exports = function tsRules() { loader: 'monic-loader', options: inherit(monic.typescript, { replacers: [].concat( - fatHTML && fatHTML !== 3 ? + fatHTML && fatHTML != 3 ? [] : include('build/monic/attach-component-dependencies'), diff --git a/build/webpack/plugins.js b/build/webpack/plugins.js index 09d840cc03..3baf1da329 100644 --- a/build/webpack/plugins.js +++ b/build/webpack/plugins.js @@ -68,7 +68,7 @@ module.exports = async function plugins({name}) { plugins.set('progress-plugin', createProgressPlugin(name)); } - const isThirdFatHTMLMode = config.webpack.fatHTML() === 3; + const isThirdFatHTMLMode = config.webpack.fatHTML() == 3; if ((config.webpack.fatHTML() || config.webpack.storybook() || config.webpack.ssr) && !isThirdFatHTMLMode) { plugins.set('limit-chunk-count-plugin', new webpack.optimize.LimitChunkCountPlugin({ From b0afc6918d91c2f8e805867986df9770003ab0a4 Mon Sep 17 00:00:00 2001 From: bonkalol Date: Sat, 28 Dec 2024 12:28:08 +0300 Subject: [PATCH 19/19] fix build --- build/webpack/plugins/async-chunks-plugin/index.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/build/webpack/plugins/async-chunks-plugin/index.js b/build/webpack/plugins/async-chunks-plugin/index.js index aaed8ad650..7d4eda6885 100644 --- a/build/webpack/plugins/async-chunks-plugin/index.js +++ b/build/webpack/plugins/async-chunks-plugin/index.js @@ -104,7 +104,10 @@ class Index { asyncChunks.forEach((chunk) => { chunk.files.forEach((file) => { - fs.rmSync(path.join(compiler.options.output.path, file)); + const pathToFile = path.join(compiler.options.output.path, file); + if (fs.existsSync(pathToFile)) { + fs.rmSync(path.join(compiler.options.output.path, file)); + } }); }); }