From 4575c38e696aa97a5e648dd82ae39f006cf7a02c Mon Sep 17 00:00:00 2001 From: Kyle Mathews Date: Tue, 21 Mar 2017 13:11:26 -0700 Subject: [PATCH] Use minChunks callback function to ensure framework code in commonsjs --- packages/gatsby/lib/bootstrap/index.js | 17 ++++----- packages/gatsby/lib/utils/query-runner.js | 26 ++++++++------ packages/gatsby/lib/utils/webpack.config.js | 40 +++++++++++++++------ packages/gatsby/package.json | 3 +- packages/gatsby/yarn.lock | 17 ++------- 5 files changed, 56 insertions(+), 47 deletions(-) diff --git a/packages/gatsby/lib/bootstrap/index.js b/packages/gatsby/lib/bootstrap/index.js index 2daf86a959068..1da5c3b174b16 100644 --- a/packages/gatsby/lib/bootstrap/index.js +++ b/packages/gatsby/lib/bootstrap/index.js @@ -33,15 +33,12 @@ process.on(`unhandledRejection`, error => { // takes control of that page component in gatsby-node. const autoPathCreator = async program => { const pagesDirectory = path.join(program.directory, `pages`) - const exts = program.extensions.map(e => `*${ e }`).join('|') - const files = await glob(`${pagesDirectory}/**/?(${ exts })`) + const exts = program.extensions.map(e => `*${e}`).join("|") + const files = await glob(`${pagesDirectory}/**/?(${exts})`) // Create initial page objects. let autoPages = files.map(filePath => ({ component: filePath, - componentChunkName: layoutComponentChunkName( - program.directory, - filePath - ), + componentChunkName: layoutComponentChunkName(program.directory, filePath), path: filePath, })) @@ -74,8 +71,8 @@ const autoPathCreator = async program => { console.log(page) console.log(chalk.bold.red(error)) } - }); - return autoPages; + }) + return autoPages } module.exports = async program => { @@ -327,8 +324,8 @@ module.exports = async program => { console.log(`added pages to in-memory db`) // Collect resolvable extensions and attach to program. - const extensions = [ `.js`, `.jsx` ] - const apiResults = await apiRunnerNode('resolvableExtensions') + const extensions = [`.js`, `.jsx`] + const apiResults = await apiRunnerNode("resolvableExtensions") program.extensions = apiResults.reduce((a, b) => a.concat(b), extensions) // TODO move this to own source plugin per component type diff --git a/packages/gatsby/lib/utils/query-runner.js b/packages/gatsby/lib/utils/query-runner.js index d57eba83178eb..7d02b1e7abeaf 100644 --- a/packages/gatsby/lib/utils/query-runner.js +++ b/packages/gatsby/lib/utils/query-runner.js @@ -6,8 +6,8 @@ import traverse from "babel-traverse" import path from "path" import parseFilepath from "parse-filepath" import glob from "glob" -import apiRunnerNode from "./api-runner-node"; -import Promise from "bluebird"; +import apiRunnerNode from "./api-runner-node" +import Promise from "bluebird" import { pagesDB, siteDB, programDB } from "./globals" import { layoutComponentChunkName, pathChunkName } from "./js-chunk-names" @@ -229,23 +229,26 @@ const q = queue( let ast // Preprocess and attempt to parse source; return an AST if we can, log an error if we can't. // I'm unconvinced that this is an especially good implementation... - const transpiled = await apiRunnerNode(`preprocessSource`, { filename: file, contents: fileStr }) + const transpiled = await apiRunnerNode(`preprocessSource`, { + filename: file, + contents: fileStr, + }) if (transpiled.length) { for (const item of transpiled) { try { const tmp = babylon.parse(item, { sourceType: `module`, - plugins: [`*`] + plugins: [`*`], }) - ast = tmp; + ast = tmp break } catch (e) { - console.info(e); + console.info(e) continue } } if (ast === undefined) { - console.error(`Failed to parse preprocessed file ${ file }`) + console.error(`Failed to parse preprocessed file ${file}`) } } else { try { @@ -269,7 +272,7 @@ const q = queue( // we're looking for a ES6 named export called "pageQuery" const name = declaration.id.name if (name === `pageQuery`) { - const type = declaration.init.type; + const type = declaration.init.type if (type === `TemplateLiteral`) { // most pageQueries will be template strings const chunks = [] @@ -282,9 +285,10 @@ const q = queue( query = declaration.init.extra.rawValue } console.time(`graphql query time`) - } else return - } - }); + } else + return + }, + }) const absFile = path.resolve(file) // Get paths for this file. const paths = [] diff --git a/packages/gatsby/lib/utils/webpack.config.js b/packages/gatsby/lib/utils/webpack.config.js index 9fb189dc755aa..f601ebabd8c3b 100644 --- a/packages/gatsby/lib/utils/webpack.config.js +++ b/packages/gatsby/lib/utils/webpack.config.js @@ -176,7 +176,8 @@ module.exports = async ( // by default in Webpack that most sites don't want. // This line disables that. // TODO remove this now that loading moment.js isn't common w/ new - // graphql data layer? + // graphql data layer? Or just move to its own package with other + // common webpack tweaks e.g. lodash? new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), new WebpackMD5Hash(), //new webpack.optimize.DedupePlugin(), @@ -189,14 +190,33 @@ module.exports = async ( // for merging in page-specific JS libs into the commons chunk. The // two principles here is a) keep the TTI (time to interaction) as // low as possible so that means keeping commons.js small with - // critical code (e.g. React) and b) is we want to push JS - // parse/eval work as close as possible to when it's used. Since - // most people don't navigate to most pages, take tradeoff of - // loading/evaling modules multiple times over loading/evaling lots - // of unused code on the initial opening of the app. - // - // Use Math.max as there must be at least two chunks. - minChunks: Math.max(3, Math.floor(components.length / 2)), + // critical framework code (e.g. React/react-router) and b) is we + // want to push JS parse/eval work as close as possible to when + // it's used. Since most people don't navigate to most pages, take + // tradeoff of loading/evaling modules multiple times over + // loading/evaling lots of unused code on the initial opening of + // the app. + minChunks: (module, count) => { + const vendorModuleList = [ + `react`, + `react-dom`, + `react-router`, + `react-router-scroll`, + `scroll-behavior`, + `history`, + ] + const isFramework = _.some( + vendorModuleList.map(vendor => { + const regex = new RegExp(`\/node_modules\/${vendor}\/`, `i`) + return regex.test(module.resource) + }) + ) + if (isFramework) { + return isFramework + } else { + return count > 3 + } + }, }), // Add a few global variables. Set NODE_ENV to production (enables // optimizations for React) and whether prefixing links is enabled @@ -251,7 +271,7 @@ module.exports = async ( function resolve() { return { // use the program's extension list (generated via the 'resolvableExtensions' API hook) - extensions: [ ``, ...program.extensions ], + extensions: [``, ...program.extensions], // Hierarchy of directories for Webpack to look for module. // First is the site directory. // Then in the special directory of isomorphic modules Gatsby ships with. diff --git a/packages/gatsby/package.json b/packages/gatsby/package.json index 835b28d4e5e3a..77efc8c55f7b1 100644 --- a/packages/gatsby/package.json +++ b/packages/gatsby/package.json @@ -138,7 +138,8 @@ "iflow-lodash": "^1.1.24", "iflow-react-router": "^1.2.1", "lerna": "2.0.0-beta.30", - "nyc": "^7.0.0" + "nyc": "^7.0.0", + "rimraf": "^2.6.1" }, "engines": { "node": ">4.0.0" diff --git a/packages/gatsby/yarn.lock b/packages/gatsby/yarn.lock index cb5fe1abbf985..6286fba39d6f1 100644 --- a/packages/gatsby/yarn.lock +++ b/packages/gatsby/yarn.lock @@ -1395,13 +1395,6 @@ circular-json@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/circular-json/-/circular-json-0.3.1.tgz#be8b36aefccde8b3ca7aa2d6afc07a37242c0d2d" -cjsx-loader@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/cjsx-loader/-/cjsx-loader-3.0.0.tgz#06dca52af2af649a8c0539c17990f633adc6dd8f" - dependencies: - coffee-react-transform "^4.0.0" - loader-utils "0.2.x" - clap@^1.0.9: version "1.1.2" resolved "https://registry.yarnpkg.com/clap/-/clap-1.1.2.tgz#316545bf22229225a2cecaa6824cd2f56a9709ed" @@ -1459,17 +1452,11 @@ code-point-at@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" -coffee-loader@^0.7.2: - version "0.7.3" - resolved "https://registry.yarnpkg.com/coffee-loader/-/coffee-loader-0.7.3.tgz#fadbc6efd6fc7ecc88c5b3046a2c292066bcb54a" - dependencies: - loader-utils "^1.0.2" - coffee-react-transform@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/coffee-react-transform/-/coffee-react-transform-4.0.0.tgz#731a79fd445a56e93926c72e983eff937f7c6fde" -coffee-script@^1.12.4, coffee-script@^1.9.1, coffee-script@^1.9.3: +coffee-script@^1.12.4, coffee-script@^1.9.1: version "1.12.4" resolved "https://registry.yarnpkg.com/coffee-script/-/coffee-script-1.12.4.tgz#fe1bced97fe1fb3927b998f2b45616e0658be1ff" @@ -6058,7 +6045,7 @@ right-align@^0.1.1: dependencies: align-text "^0.1.1" -rimraf@2, rimraf@^2.2.8, rimraf@^2.3.2, rimraf@^2.3.3, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2.5.4: +rimraf@2, rimraf@^2.2.8, rimraf@^2.3.2, rimraf@^2.3.3, rimraf@^2.4.3, rimraf@^2.4.4, rimraf@^2.5.4, rimraf@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.6.1.tgz#c2338ec643df7a1b7fe5c54fa86f57428a55f33d" dependencies: