diff --git a/packages/next/build/webpack-config.ts b/packages/next/build/webpack-config.ts index 74b044cdaed42..a558320eca9ce 100644 --- a/packages/next/build/webpack-config.ts +++ b/packages/next/build/webpack-config.ts @@ -229,13 +229,11 @@ export default async function getBaseWebpackConfig( }, }, prodGranular: { - chunks: 'initial', + chunks: 'all', cacheGroups: { default: false, vendors: false, framework: { - // Framework chunk applies to modules in dynamic chunks, unlike shared chunks - // TODO(atcastle): Analyze if other cache groups should be set to 'all' as well chunks: 'all', name: 'framework', // This regex ignores nested copies of framework libraries so they're diff --git a/packages/next/build/webpack/plugins/build-manifest-plugin.ts b/packages/next/build/webpack/plugins/build-manifest-plugin.ts index 3a7cc24050c95..0fae803aa88fc 100644 --- a/packages/next/build/webpack/plugins/build-manifest-plugin.ts +++ b/packages/next/build/webpack/plugins/build-manifest-plugin.ts @@ -95,29 +95,24 @@ export default class BuildManifestPlugin { } const filesForEntry: string[] = [] - for (const chunk of entrypoint.chunks) { - // If there's no name or no files - if (!chunk.name || !chunk.files) { + + // getFiles() - helper function to read the files for an entrypoint from stats object + for (const file of entrypoint.getFiles()) { + if (/\.map$/.test(file) || /\.hot-update\.js$/.test(file)) { continue } - for (const file of chunk.files) { - if (/\.map$/.test(file) || /\.hot-update\.js$/.test(file)) { - continue - } - - // Only `.js` and `.css` files are added for now. In the future we can also handle other file types. - if (!/\.js$/.test(file) && !/\.css$/.test(file)) { - continue - } - - // The page bundles are manually added to _document.js as they need extra properties - if (IS_BUNDLED_PAGE_REGEX.exec(file)) { - continue - } + // Only `.js` and `.css` files are added for now. In the future we can also handle other file types. + if (!/\.js$/.test(file) && !/\.css$/.test(file)) { + continue + } - filesForEntry.push(file.replace(/\\/g, '/')) + // The page bundles are manually added to _document.js as they need extra properties + if (IS_BUNDLED_PAGE_REGEX.exec(file)) { + continue } + + filesForEntry.push(file.replace(/\\/g, '/')) } assetMap.pages[`/${pagePath.replace(/\\/g, '/')}`] = [ diff --git a/test/integration/chunking/pages/page2.js b/test/integration/chunking/pages/page2.js index da406cf03261a..51a6a3cd9dd42 100644 --- a/test/integration/chunking/pages/page2.js +++ b/test/integration/chunking/pages/page2.js @@ -1,14 +1,23 @@ -import * as _ from 'lodash' +import { useState, useEffect } from 'react' +import _ from 'lodash' import dynamic from 'next/dynamic' +import Link from 'next/link' const One = dynamic(() => import('../components/one')) const Page = () => { + const [str, setStr] = useState('rad') + useEffect(() => { + setStr(_.pad(str, 7, '_')) + }, []) + console.log(_) return (
page2 +

{str}

+ Page3
) } diff --git a/test/integration/chunking/pages/page3.js b/test/integration/chunking/pages/page3.js new file mode 100644 index 0000000000000..d5d7d6c4559d9 --- /dev/null +++ b/test/integration/chunking/pages/page3.js @@ -0,0 +1,13 @@ +import Link from 'next/link' +import('lodash').then(_ => console.log(_.chunk(['a', 'b', 'c', 'd'], 2))) + +const Page = () => { + return ( +
+

Page3

+ Page2 +
+ ) +} + +export default Page diff --git a/test/integration/chunking/test/index.test.js b/test/integration/chunking/test/index.test.js index a30901aa45c73..f0c71b2f4aa0e 100644 --- a/test/integration/chunking/test/index.test.js +++ b/test/integration/chunking/test/index.test.js @@ -1,9 +1,16 @@ /* eslint-env jest */ /* global jasmine */ import { join } from 'path' -import { nextBuild } from 'next-test-utils' +import { + nextBuild, + findPort, + waitFor, + nextStart, + killApp +} from 'next-test-utils' import { readdir, readFile, unlink, access } from 'fs-extra' import cheerio from 'cheerio' +import webdriver from 'next-webdriver' jasmine.DEFAULT_TIMEOUT_INTERVAL = 1000 * 60 * 1 @@ -30,7 +37,12 @@ describe('Chunking', () => { } catch (e) { // Error here means old chunks don't exist, so we don't need to do anything } - await nextBuild(appDir) + const { stdout, stderr } = await nextBuild(appDir, [], { + stdout: true, + stderr: true + }) + console.log(stdout) + console.error(stderr) stats = (await readFile(join(appDir, '.next', 'stats.json'), 'utf8')) // fixes backslashes in keyNames not being escaped on windows .replace(/"static\\(.*?":)/g, '"static\\\\$1') @@ -95,4 +107,19 @@ describe('Chunking', () => { }) expect(misplacedReactDom).toBe(false) }) + + it('should hydrate with granularChunks config', async () => { + const appPort = await findPort() + const app = await nextStart(appDir, appPort) + + const browser = await webdriver(appPort, '/page2') + await waitFor(1000) + const text = await browser.elementByCss('#padded-str').text() + + expect(text).toBe('__rad__') + + await browser.close() + + await killApp(app) + }) })