Skip to content

Commit

Permalink
fix: expose used chunkNames from a server. Fixes #587
Browse files Browse the repository at this point in the history
  • Loading branch information
theKashey committed Jul 2, 2020
1 parent fb0cc38 commit 831aec0
Show file tree
Hide file tree
Showing 11 changed files with 331 additions and 216 deletions.
3 changes: 2 additions & 1 deletion examples/server-side-rendering/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
"build": "NODE_ENV=production yarn build:webpack && yarn build:lib",
"build:webpack": "webpack",
"build:lib": "babel -d lib src",
"start": "NODE_ENV=production node lib/server/main.js"
"start": "NODE_ENV=production node lib/server/main.js",
"link:all": "yarn link @loadable/babel-plugin && yarn link @loadable/server && yarn link @loadable/component"
},
"devDependencies": {
"@babel/cli": "^7.4.4",
Expand Down
3 changes: 2 additions & 1 deletion packages/babel-plugin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,6 @@
},
"peerDependencies": {
"@babel/core": "^7.0.0-0"
}
},
"gitHead": "fb0cc38902f70fe4446a5f72824c25fc27f66c6d"
}
5 changes: 3 additions & 2 deletions packages/codemod/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "loadable-codemod",
"description": "Various codemods related to @loadable/components for easier migration/ugprades.",
"description": "Various codemods related to @loadable/components for easier migration/upgrades.",
"version": "5.13.0",
"repository": "git@github.com:gregberge/loadable-components.git",
"author": "Jacky Efendi <jacky.efendi1@gmail.com>",
Expand Down Expand Up @@ -31,5 +31,6 @@
"execa": "^4.0.0",
"jscodeshift": "0.7.0",
"yargs": "^15.1.0"
}
},
"gitHead": "fb0cc38902f70fe4446a5f72824c25fc27f66c6d"
}
12 changes: 6 additions & 6 deletions packages/component/.size-snapshot.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
{
"dist/loadable.cjs.js": {
"bundled": 13566,
"minified": 6556,
"gzipped": 2340
"bundled": 13945,
"minified": 6737,
"gzipped": 2397
},
"dist/loadable.esm.js": {
"bundled": 13187,
"minified": 6252,
"gzipped": 2269,
"bundled": 13566,
"minified": 6433,
"gzipped": 2326,
"treeshaked": {
"rollup": {
"code": 276,
Expand Down
3 changes: 2 additions & 1 deletion packages/component/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,5 +40,6 @@
"@babel/runtime": "^7.7.7",
"hoist-non-react-statics": "^3.3.1",
"react-is": "^16.12.0"
}
},
"gitHead": "fb0cc38902f70fe4446a5f72824c25fc27f66c6d"
}
26 changes: 18 additions & 8 deletions packages/component/src/loadableReady.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
/* eslint-disable no-underscore-dangle, camelcase */
/* eslint-env browser */
import { warn } from './util'
import { getRequiredChunkKey } from './sharedInternals'
import {warn} from './util'
import {getRequiredChunkKey} from './sharedInternals'
import {LOADABLE_SHARED} from "./shared";

const BROWSER = typeof window !== 'undefined'

export default function loadableReady(
done = () => {},
{ namespace = '' } = {},
done = () => {
},
{namespace = ''} = {},
) {
if (!BROWSER) {
warn('`loadableReady()` must be called in browser only')
Expand All @@ -18,12 +19,21 @@ export default function loadableReady(

let requiredChunks = null
if (BROWSER) {
const dataElement = document.getElementById(getRequiredChunkKey(namespace))
const id = getRequiredChunkKey(namespace)
const dataElement = document.getElementById(id)
if (dataElement) {
requiredChunks = JSON.parse(dataElement.textContent);
requiredChunks.forEach(chunk => {
LOADABLE_SHARED.initialChunks[chunk] = true;
});

const extElement = document.getElementById(`${id}_ext`);
if (extElement) {
const {namedChunks} = JSON.parse(extElement.textContent);
namedChunks.forEach(chunkName => {
LOADABLE_SHARED.initialChunks[chunkName] = true;
});
} else {
// version mismatch
throw new Error('loadable-component: @loabable/server does not match @loadable/component');
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion packages/server/__fixtures__/stats.json
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@
},
"letters-A": {
"chunks": [
"letters-A"
"chunk-0-for-letters-A"
],
"assets": [
"letters-A.css",
Expand Down
3 changes: 2 additions & 1 deletion packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,6 @@
},
"dependencies": {
"lodash": "^4.17.15"
}
},
"gitHead": "fb0cc38902f70fe4446a5f72824c25fc27f66c6d"
}
74 changes: 47 additions & 27 deletions packages/server/src/ChunkExtractor.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@ import uniq from 'lodash/uniq'
import uniqBy from 'lodash/uniqBy'
import flatMap from 'lodash/flatMap'
import React from 'react'
import { invariant, getRequiredChunkKey } from './sharedInternals'
import {invariant, getRequiredChunkKey} from './sharedInternals'
import ChunkExtractorManager from './ChunkExtractorManager'
import { smartRequire, joinURLPath } from './util'
import {smartRequire, joinURLPath} from './util'

const EXTENSION_SCRIPT_TYPES = {
'.js': 'script',
Expand Down Expand Up @@ -64,7 +64,7 @@ function assetToScriptElement(asset, extraProps) {
)
}

function assetToStyleString(asset, { inputFileSystem }) {
function assetToStyleString(asset, {inputFileSystem}) {
return new Promise((resolve, reject) => {
inputFileSystem.readFile(asset.path, 'utf8', (err, data) => {
if (err) {
Expand All @@ -82,7 +82,7 @@ function assetToStyleTag(asset, extraProps) {
}"${getSriHtmlAttributes(asset)}${extraPropsToString(asset, extraProps)}>`
}

function assetToStyleTagInline(asset, extraProps, { inputFileSystem }) {
function assetToStyleTagInline(asset, extraProps, {inputFileSystem}) {
return new Promise((resolve, reject) => {
inputFileSystem.readFile(asset.path, 'utf8', (err, data) => {
if (err) {
Expand Down Expand Up @@ -113,7 +113,7 @@ function assetToStyleElement(asset, extraProps) {
)
}

function assetToStyleElementInline(asset, extraProps, { inputFileSystem }) {
function assetToStyleElementInline(asset, extraProps, {inputFileSystem}) {
return new Promise((resolve, reject) => {
inputFileSystem.readFile(asset.path, 'utf8', (err, data) => {
if (err) {
Expand All @@ -124,7 +124,7 @@ function assetToStyleElementInline(asset, extraProps, { inputFileSystem }) {
<style
key={asset.url}
data-chunk={asset.chunk}
dangerouslySetInnerHTML={{ __html: data }}
dangerouslySetInnerHTML={{__html: data}}
{...handleExtraProps(asset, extraProps)}
/>,
)
Expand Down Expand Up @@ -172,14 +172,14 @@ function isValidChunkAsset(chunkAsset) {

class ChunkExtractor {
constructor({
statsFile,
stats,
entrypoints = ['main'],
namespace = '',
outputPath,
publicPath,
inputFileSystem = fs,
} = {}) {
statsFile,
stats,
entrypoints = ['main'],
namespace = '',
outputPath,
publicPath,
inputFileSystem = fs,
} = {}) {
this.namespace = namespace
this.stats = stats || smartRequire(statsFile)
this.publicPath = publicPath || this.stats.publicPath
Expand All @@ -200,7 +200,7 @@ class ChunkExtractor {
return chunkGroup
}

createChunkAsset({ filename, chunk, type, linkType }) {
createChunkAsset({filename, chunk, type, linkType}) {
return {
filename,
scriptType: extensionToScriptType(
Expand Down Expand Up @@ -279,27 +279,47 @@ class ChunkExtractor {
return JSON.stringify(this.getChunkDependencies(this.chunks))
}

getRequiredChunksNamesScriptContent() {
return JSON.stringify({
namedChunks: this.chunks,
})
}

getRequiredChunksScriptTag(extraProps) {
return `<script id="${getRequiredChunkKey(
this.namespace,
)}" type="application/json"${extraPropsToString(
const id = getRequiredChunkKey(this.namespace);
const props = `type="application/json"${extraPropsToString(
null,
extraProps,
)}>${this.getRequiredChunksScriptContent()}</script>`
)}`;
return [
`<script id="${id}" ${props}>${this.getRequiredChunksScriptContent()}</script>`,
`<script id="${id}_ext" ${props}>${this.getRequiredChunksNamesScriptContent()}</script>`,
].join('');
}

getRequiredChunksScriptElement(extraProps) {
return (
const id = getRequiredChunkKey(this.namespace);
const props = {
type: "application/json",
...handleExtraProps(null, extraProps)
}
return [
<script
key="required"
id={getRequiredChunkKey(this.namespace)}
type="application/json"
id={id}
dangerouslySetInnerHTML={{
__html: this.getRequiredChunksScriptContent(),
}}
{...handleExtraProps(null, extraProps)}
{...props}

/>,
<script
id={`${id}_ext`}
dangerouslySetInnerHTML={{
__html: this.getRequiredChunksNamesScriptContent(),
}}
{...props}
/>
)
]
}

// Public methods
Expand All @@ -325,7 +345,7 @@ class ChunkExtractor {
invariant(mainAsset, 'asset not found')

this.stats.assets
.filter(({ name }) => {
.filter(({name}) => {
const type = extensionToScriptType(
path
.extname(name)
Expand All @@ -334,7 +354,7 @@ class ChunkExtractor {
)
return type === 'script'
})
.forEach(({ name }) => {
.forEach(({name}) => {
smartRequire(path.join(this.outputPath, name.split('?')[0]))
})

Expand Down

0 comments on commit 831aec0

Please sign in to comment.