-
Notifications
You must be signed in to change notification settings - Fork 683
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
V4P2: feat(buildpack): Add Webpack configurator facade #1498
Conversation
This pull request is automatically deployed with Now. Latest deployment for this branch: https://pwa-studio-git-zetlen-v4apip2-webpack-facade.mmansoor.now.sh |
|
94383d6
to
6733cec
Compare
6733cec
to
87edf4d
Compare
87edf4d
to
984ef97
Compare
@@ -7,6 +7,8 @@ jest.mock('../../Utilities/configureHost'); | |||
const fs = require('fs'); | |||
jest.spyOn(fs, 'readFile'); | |||
|
|||
const mockContext = require('path').resolve(__dirname, '../../../../../'); | |||
|
|||
const debugErrorMiddleware = require('debug-error-middleware'); | |||
const waitForExpect = require('wait-for-expect'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This dependency no longer exists, this line can be removed. I believe this is the only reference to waitForExpect
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I found more in tests for useQuery, useRestApi, and magentoRouteHandler.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, the dependency is still there. Instead of listing it at root I added it to Buildpack and Peregrine, the two places it's used.
@@ -60,7 +60,8 @@ const reducer = (prevState = initialState, action = {}) => { | |||
} | |||
}; | |||
|
|||
const ToastContext = createContext(); | |||
const ToastContext = | |||
window.__ToastContext || (window.__ToastContext = createContext()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this creating multiple toast contexts previously?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, this line confuses me, especially since window.__ToastContext
is not referenced anywhere else. If there's a bug with this particular context object, we should diagnose it and fix it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't know how this change made it in here: must have been a bad old rebase. Removed.
"name": "DEVELOPER_DEBUG_BUNDLES", | ||
"type": "bool", | ||
"desc": "Build developer-mode bundles without adding hot reloading or launching the dev server. Disables minification and enables all Webpack debug settings for maximum code readability.", | ||
"default": false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice 👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this just developer mode
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, if I set this to true
, yarn watch:all
and yarn watch:venia
no longer serve properly. Not sure what's going on.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, it's busted because of some bad choices in the informed
library.
clearTimeout(timeout); | ||
resolve({ | ||
key: certBuffers.key.toString('utf8'), | ||
cert: certBuffers.cert.toString('utf8') | ||
}); | ||
} catch (e) { | ||
clearTimeout(timeout); | ||
debug('failure! cleared UI timeout for getCert("%s")', hostname); | ||
debug(e); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like there are some debug
calls you can clear out of here if you want.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I joined those two together, but debug calls are cheap and they should be plentiful.
TRAPPING_MONK: 'level 1', | ||
TRAPPING_ELF: 'level 2', | ||
GEWGAW_PALADIN: 'level 3', | ||
GEWGAW_ROGUE: 'level 4', | ||
MUSTANG_SALLY: 'level a million' | ||
GEWGAW_ROGUE: 'level 4' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is hilarious lol
}), | ||
new UpwardIncludePlugin({ | ||
upwardDirs: hasFlag('upward') | ||
}), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was kind of expecting us not to include the UpwardIncludePlugin
at all if hasFlag('upward')
is false
.
Does the plugin fail gracefully without any upwardDirs
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was kind of expecting us not to include the
UpwardIncludePlugin
at all ifhasFlag('upward')
isfalse
.
Minor correction: hasFlag("upward")
can't be false
; it would return []
if no packages had that flag.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@supernova-at Good catch! We should always require an upward file in the app itself.
const UpwardPlugin = require('../UpwardPlugin'); | ||
const UpwardDevServerPlugin = require('../UpwardDevServerPlugin'); | ||
|
||
const mockContext = require('path').resolve(__dirname, '../../../../../../'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the path to our project root I'm guessing? If so, may want to drop a comment or rename the variable projectRoot
or something
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A comment would suffice, I think.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Comment added.
|
||
### `ConfigureWebpackOptions | ||
|
||
TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just highlighting this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd like to see this filled out before we merge. At least copy in what was written in the PR description :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Agreed. I'll update you.
|
||
## Example | ||
|
||
TODO |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just highlighting this
@@ -78,13 +78,37 @@ The Venia Adapter wraps around Venia components to satisfy any implicit external | |||
|
|||
### Venia drivers | |||
|
|||
The [`@magento/venia-drivers`][] dependency is a _virtual module_ for centralizing the external dependencies of Venia components that use them, such as GraphQL clients and Redux stores. | |||
Instead of importing these dependencies directly, Venia components import them from `src/drivers`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this repeating L92 & L93?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we drop L92 & L93?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since @jcalcaben wrote L92 and L93 I'd rather drop these lines, which I've done.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
18/72 files viewed. Left some comments for now.
"@babel/preset-env": "^7.3.4", | ||
"@babel/runtime": "^7.4.2", | ||
"babel-plugin-dynamic-import-node": "^2.2.0", | ||
"babel-plugin-graphql-tag": "^2.0.0" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Was this change (all of these dependencies moving from tilde
to caret
) intentional?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, this was a mistake. Reverted!
packages/peregrine/package.json
Outdated
"jsnext:main": "lib/index.js", | ||
"es2015": "lib/index.js", | ||
"sideEffects": false | ||
"esnext": "lib/index.js", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this supersede jsnext:main
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The precedence order is in MagentoResolver
, under browserFields
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original idea was to support proposals for this convention from several different projects, for maximum compatibility. Rollup, SystemJS, etc. I think that's beyond scope, so we can just set our own aliases.
modules: [options.paths.root, 'node_modules'], | ||
mainFiles: ['index'], | ||
extensions: ['.mjs', '.js', '.json', '.graphql'] | ||
mainFields: ['esnext', 'es2015', 'module', 'browser', 'main'], | ||
extensions: ['.wasm', '.mjs', '.js', '.json', '.graphql'] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IIRC, one optimization to make webpack resolve a lot faster is to cut this field down to just [.js]
, precluding the need to resolve them in order. I'm surprised we aren't already doing it, actually; could we do it here?
Not only are the other extensions rarely imported, we already tend to include them explicitly for clarity's sake.
// safe to assume `./foo` refers to `foo.js` or `foo/index.js`
import Foo from "./foo"
// by explicitly appending `.css`, we avoid ambiguity or surprise
import defaultClasses from "./foo.css"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not seeing that advantage reliably when I try that. With no cache it's always around 50 seconds, and with full cache it's always around 20.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also leaving evening feedback so far. Still have more to look at.
@@ -60,7 +60,8 @@ const reducer = (prevState = initialState, action = {}) => { | |||
} | |||
}; | |||
|
|||
const ToastContext = createContext(); | |||
const ToastContext = | |||
window.__ToastContext || (window.__ToastContext = createContext()); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this necessary? I feel like you told me you worked this out in the past and didn't have to do this.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wasn't even supposed to be here, I've removed it :)
parsed: {} | ||
}); | ||
loadEnvCliBuilder.handler({ directory: '.' }); | ||
expect(process.exit).toHaveBeenCalled(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests in aws pipeline are failing on this assertion. Can you investigate?
@@ -5,7 +5,8 @@ const { zipObject } = require('lodash'); | |||
const isPrimitive = require('./isPrimitive'); | |||
|
|||
class ResolverVisitor { | |||
constructor(io, rootDefinition, context) { | |||
constructor(upwardPath, io, rootDefinition, context) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Technically breaking change to upward-js
, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I noticed we are modifying lots of input args. In general I think it's safer to append new arguments instead of prepend.
Also, some docs on this file would go a long way :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I suppose this shouldn't be a prepend :/ I'll refactor it
|
||
// A DevServer generates its own unique output path at startup. It needs | ||
// to assign the main outputPath to this value as well. | ||
// '@magento/venia-library': { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
placeholder?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For demo purposes.
e96f0ed
to
e7fc5a9
Compare
Co-Authored-By: Jimmy Sanford <[email protected]>
Hey @jcalcaben, I'd like your overt approval before merging this. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doc changes and drafts look good to me
Description
Pull complex Webpack configuration out of the Venia app and put it in an opinionated Buildpack utility.
This replaces most of the large webpack.config.js file in Venia. The entire PWA Studio runtime depends on the logic in that file; Peregrine, Buildpack, and UpwardJS make assumptions based on that file's configuration, which is an antipattern.
This PR adds a
configureWebpack()
function which returns a Promise for a Webpack configuration object. It takes parameters for a subset of configuration options, including:context
: Absolute path of the project root to ensure consistent behavior no matter the working directory; if webpack.config.js is in project root then this should be simply__dirname
.vendor
: Names of modules to bundle into a commons bundle. Set to a sensible default list in Venia.special
: Map of modules to flag as containing 'special' functionality, to be treated differently by the Webpack plugin and loader chain. Keys should be module names. Values should be one or more of the following flags:esModules
: Denotes that JS code for this module must adhere to thebabel-preset-peregrine
Babel preset. Code will be imported as modules using the same loader chain as local application code, enabling tree-shaking on node_modules dependencies.cssModules
: Denotes that CSS code for this module must assign all CSS imports to a variable, to receive an object of dynamically generated CSS classes. Style will be imported using the same loader chain as local application stylesheets, enabling total CSS modularity.graphQLQueries
: Denotes that JS code for this module contains GraphQL queries embedded in calls to thegraphql-tag
template literal. GraphQL will be preprocessed using the same loader chain as local application code.rootComponents
: Denotes that this module includes asrc/RootComponents
orlib/RootComponents
directory containing RootComponents to be processed by theRootComponentsPlugin
. These RootComponents will be added to the map of all RootComponent mappings available to the application.upward
: Denotes that this module includes anupward.yml
file at root declaring some subset of server-side behavior it requires and/or supplies. This file will be merged, along with theupward.yml
for any other modules you configure with this flag. It will merge down to a finalupward.yml
file produced as a build asset.Also adds a lot of debuggability to Buildpack, and cleans up some of its APIs.
Closes #1502 along with #1497 and #1499.
ℹ️ Docs and tests TODO.
Verification Steps
yarn run build
.packages/venia-concept/webpack.config.js
.Proposed Labels for Change Type/Package
Checklist: