Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(CLI): add a flag for Yarn Plug'n'Play #1

Closed
wants to merge 4 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions packages/gatsby-cli/package.json
Expand Up @@ -25,6 +25,7 @@
"opentracing": "^0.14.3",
"pretty-error": "^2.1.1",
"resolve-cwd": "^2.0.0",
"semver": "^5.6.0",
"source-map": "^0.5.7",
"stack-trace": "^0.0.10",
"update-notifier": "^2.3.0",
Expand Down
10 changes: 8 additions & 2 deletions packages/gatsby-cli/src/create-cli.js
Expand Up @@ -298,10 +298,16 @@ module.exports = (argv, handlers) => {
.command({
command: `new [rootPath] [starter]`,
desc: `Create new Gatsby project.`,
builder: _ =>
_.option(`use-pnp`, {
default: false,
type: `boolean`,
describe: `Turn on to use Yarn Plug'n'Play`,
}),
handler: handlerP(
({ rootPath, starter = `gatsbyjs/gatsby-starter-default` }) => {
({ rootPath, starter = `gatsbyjs/gatsby-starter-default`, usePnp }) => {
const initStarter = require(`./init-starter`)
return initStarter(starter, { rootPath })
return initStarter(starter, { rootPath, usePnp })
}
),
})
Expand Down
65 changes: 57 additions & 8 deletions packages/gatsby-cli/src/init-starter.js
Expand Up @@ -7,6 +7,7 @@ const sysPath = require(`path`)
const report = require(`./reporter`)
const url = require(`url`)
const existsSync = require(`fs-exists-cached`).sync
const semver = require(`semver`)

const spawn = (cmd: string) => {
const [file, ...args] = cmd.split(/\s+/)
Expand All @@ -27,15 +28,56 @@ const shouldUseYarn = () => {
}
}

const checkYarnVersion = () => {
let hasMinYarnPnp = false
let yarnVersion = null
try {
yarnVersion = execSync(`yarnpkg --version`)
.toString()
.trim()
hasMinYarnPnp = semver.gte(yarnVersion, `1.12.0`)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will have to update this after yarnpkg/yarn#6682 comes out (since Gatsby has a dependency, relay-compiler which is affected by this bug)

} catch (err) {
// ignore
}
return {
hasMinYarnPnp: hasMinYarnPnp,
yarnVersion: yarnVersion,
}
}

// Executes `npm install` or `yarn install` in rootPath.
const install = async rootPath => {
const install = async ({ rootPath, usePnp }: Options) => {
const prevDir = process.cwd()

report.info(`Installing packages...`)
process.chdir(rootPath)

try {
let cmd = shouldUseYarn() ? spawn(`yarnpkg`) : spawn(`npm install`)
let cmd
if (shouldUseYarn()) {
const yarnInfo = checkYarnVersion()
const args = []
if (usePnp) {
if (!yarnInfo.hasMinYarnPnp) {
if (yarnInfo.yarnVersion) {
report.warn(
`You are using Yarn ${
yarnInfo.yarnVersion
} together with the --use-pnp flag, but Plug'n'Play is only supported starting from the 1.12 release.\n\n` +
`Please update to Yarn 1.12 or higher for a better, fully supported experience.\n`
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will need to update this with the version that comes out of yarnpkg/yarn#6682

)
}
// 1.11 had an issue with webpack-dev-middleware, so better not use PnP with it (never reached stable, but still)
} else {
args.push(`--enable-pnp`)
}
}

cmd = execa(`yarnpkg`, args, { stdio: `inherit` })
} else {
cmd = spawn(`npm install`)
}

await cmd
} finally {
process.chdir(prevDir)
Expand All @@ -44,8 +86,13 @@ const install = async rootPath => {

const ignored = path => !/^\.(git|hg)$/.test(sysPath.basename(path))

type Options = {
rootPath: string,
usePnp: boolean,
}

// Copy starter from file system.
const copy = async (starterPath: string, rootPath: string) => {
const copy = async (starterPath: string, { rootPath, usePnp }: Options) => {
// Chmod with 755.
// 493 = parseInt('755', 8)
await fs.mkdirp(rootPath, { mode: 493 })
Expand All @@ -71,13 +118,13 @@ const copy = async (starterPath: string, rootPath: string) => {

report.success(`Created starter directory layout`)

await install(rootPath)
await install({ rootPath, usePnp })

return true
}

// Clones starter from URI.
const clone = async (hostInfo: any, rootPath: string) => {
const clone = async (hostInfo: any, { rootPath, usePnp }: Options) => {
let url
// Let people use private repos accessed over SSH.
if (hostInfo.getDefaultRepresentation() === `sshurl`) {
Expand All @@ -97,18 +144,20 @@ const clone = async (hostInfo: any, rootPath: string) => {

await fs.remove(sysPath.join(rootPath, `.git`))

await install(rootPath)
await install({ rootPath, usePnp })
}

type InitOptions = {
rootPath?: string,
usePnp?: boolean,
}

/**
* Main function that clones or copies the starter.
*/
module.exports = async (starter: string, options: InitOptions = {}) => {
const rootPath = options.rootPath || process.cwd()
const usePnp = options.usePnp || false

const urlObject = url.parse(rootPath)
if (urlObject.protocol && urlObject.host) {
Expand All @@ -124,6 +173,6 @@ module.exports = async (starter: string, options: InitOptions = {}) => {
}

const hostedInfo = hostedGitInfo.fromUrl(starter)
if (hostedInfo) await clone(hostedInfo, rootPath)
else await copy(starter, rootPath)
if (hostedInfo) await clone(hostedInfo, { rootPath, usePnp })
else await copy(starter, { rootPath, usePnp })
}
4 changes: 4 additions & 0 deletions packages/gatsby/package.json
Expand Up @@ -17,6 +17,7 @@
"@babel/runtime": "^7.0.0",
"@babel/traverse": "^7.0.0",
"@reach/router": "^1.1.1",
"address": "^1.0.3",
"autoprefixer": "^8.6.5",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "^8.2.2",
Expand All @@ -25,6 +26,7 @@
"babel-plugin-dynamic-import-node": "^1.2.0",
"babel-plugin-remove-graphql-queries": "^2.5.1",
"babel-preset-gatsby": "^0.1.3",
"babel-traverse": "^6.26.0",
"better-queue": "^3.8.6",
"bluebird": "^3.5.0",
"cache-manager": "^2.9.0",
Expand Down Expand Up @@ -57,6 +59,7 @@
"file-loader": "^1.1.11",
"flat": "^4.0.0",
"friendly-errors-webpack-plugin": "^1.6.1",
"fs-exists-cached": "^1.0.0",
"fs-extra": "^5.0.0",
"gatsby-cli": "^2.4.5",
"gatsby-link": "^2.0.6",
Expand Down Expand Up @@ -93,6 +96,7 @@
"optimize-css-assets-webpack-plugin": "^5.0.1",
"parse-filepath": "^1.0.1",
"physical-cpu-count": "^2.0.0",
"pnp-webpack-plugin": "^1.2.0",
"postcss-flexbugs-fixes": "^3.0.0",
"postcss-loader": "^2.1.3",
"raw-loader": "^0.5.1",
Expand Down
11 changes: 11 additions & 0 deletions packages/gatsby/src/utils/webpack.config.js
Expand Up @@ -4,6 +4,7 @@ const fs = require(`fs-extra`)
const path = require(`path`)
const dotenv = require(`dotenv`)
const FriendlyErrorsWebpackPlugin = require(`friendly-errors-webpack-plugin`)
const PnpWebpackPlugin = require(`pnp-webpack-plugin`)
const { store } = require(`../redux`)
const { actions } = require(`../redux/actions`)
const debug = require(`debug`)(`gatsby:webpack-config`)
Expand Down Expand Up @@ -350,6 +351,11 @@ module.exports = async (
function getResolve() {
const { program } = store.getState()
return {
plugins: [
// Adds support for installing with Plug'n'Play, leading to faster installs and adding
// guards against forgotten dependencies and such.
PnpWebpackPlugin,
],
// Use the program's extension list (generated via the
// 'resolvableExtensions' API hook).
extensions: [...program.extensions],
Expand Down Expand Up @@ -392,6 +398,11 @@ module.exports = async (
}

return {
plugins: [
// Also related to Plug'n'Play, but this time it tells Webpack to load its loaders
// from the current package.
PnpWebpackPlugin.moduleLoader(module),
],
modules: [...root, path.join(__dirname, `../loaders`), `node_modules`],
}
}
Expand Down
3 changes: 3 additions & 0 deletions packages/graphql-skip-limit/package.json
Expand Up @@ -16,6 +16,9 @@
"cross-env": "^5.1.4",
"graphql": "^0.13.2"
},
"peerDependencies": {
"graphql": "^0.13.2"
},
"homepage": "https://github.com/gatsbyjs/gatsby/tree/master/packages/graphql-skip-limit#readme",
"keywords": [
"gatsby",
Expand Down
19 changes: 18 additions & 1 deletion yarn.lock
Expand Up @@ -1991,7 +1991,7 @@ add-stream@^1.0.0:
resolved "https://registry.yarnpkg.com/add-stream/-/add-stream-1.0.0.tgz#6a7990437ca736d5e1288db92bd3266d5f5cb2aa"
integrity sha1-anmQQ3ynNtXhKI25K9MmbV9csqo=

address@1.0.3, address@^1.0.1:
address@1.0.3, address@^1.0.1, address@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9"
integrity sha512-z55ocwKBRLryBs394Sm3ushTtBeg6VAeuku7utSoSnsJKvKcnXFIyC6vh27n3rXyxSgkJBBCAvyOn7gSUcTYjg==
Expand Down Expand Up @@ -14665,6 +14665,13 @@ pngquant-bin@^5.0.0:
execa "^0.10.0"
logalot "^2.0.0"

pnp-webpack-plugin@^1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/pnp-webpack-plugin/-/pnp-webpack-plugin-1.2.0.tgz#a85338bc313b8a0469c1d8c5c5d016873be47cb2"
integrity sha512-cCaqL7SZCqeJoCEL5GhSGU9CFJOMcDIEAS83X+0m2q25vtt9IqrMJ5dObm8WyqnM4CHRaIn0VVkn7RXdZ0C6Kg==
dependencies:
ts-pnp "^1.0.0"

portfinder@^1.0.9:
version "1.0.17"
resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.17.tgz#a8a1691143e46c4735edefcf4fbcccedad26456a"
Expand Down Expand Up @@ -16882,6 +16889,11 @@ semver@^4.0.3:
resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da"
integrity sha1-MAvG4OhjdPe6YQaLWx7NV/xlMto=

semver@^5.6.0:
version "5.6.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.6.0.tgz#7e74256fbaa49c75aa7c7a205cc22799cac80004"
integrity sha512-RS9R6R35NYgQn++fkDWaOmqGoj4Ek9gGs+DPxNUZKuwE183xjJroKvyo1IzVFeXvUrvmALy6FWD5xrdJT25gMg==

semver@~5.3.0:
version "5.3.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"
Expand Down Expand Up @@ -18659,6 +18671,11 @@ trough@^1.0.0:
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.3.tgz#e29bd1614c6458d44869fc28b255ab7857ef7c24"
integrity sha512-fwkLWH+DimvA4YCy+/nvJd61nWQQ2liO/nF/RjkTpiOGi+zxZzVkhb1mvbHIIW4b/8nDsYI8uTmAlc0nNkRMOw==

ts-pnp@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/ts-pnp/-/ts-pnp-1.0.0.tgz#44a3a9e8c13fcb711bcda75d7b576c21af120c9d"
integrity sha512-qgwM7eBrxFvZSXLtSvjf3c2mXwJOOGD49VlE+KocUGX95DuMdLc/psZHBnPpZL5b2NU7VtQGHRCWF3cNfe5kxQ==

tsickle@^0.27.2:
version "0.27.5"
resolved "https://registry.yarnpkg.com/tsickle/-/tsickle-0.27.5.tgz#41e1a41a5acf971cbb2b0558a9590779234d591f"
Expand Down