Overview
This new minor release v0.31.0 focuses on greater ecosystem compatibility through a significant refactor of how import maps are generated and better handling of the exports map specification, as well as how node_modules are resolved generally. This includes libraries (Shoelace, Spectrum Web Components) as well as package managers like pnpm. The minimum version of NodeJS LTS was also bumped. (see the breaking changes section of the release notes).
# npm
$ npm i -D @greenwood/cli@latest
# Yarn 1.x (classic)
$ yarn upgrade @greenwood/cli@latest --dev
# pnpm
$ pnpm i -D @greenwood/cli@latest
Changelog
https://github.com/ProjectEvergreen/greenwood/issues?q=label%3Av0.31.0
- improve support for package.json exports when building up import maps
- leverage
import.meta.resolve
to support import maps generation and accurate node_modules resolution when building - walk package error if @spectrum-web-components/action-menu is installed even if not used
- support non-JavaScript file formats for import maps
- Improve PNPM support
- Import Attributes support in Acorn
- not all expected modern JavaScript syntax supported
- leverage
import.meta.resolve
to support import maps generation and accurate node_modules resolution when building - Improve PNPM support
- bare CSS
@import
specifiers are not resolving and bundling correctly - better document and clarify Lit SSR plugin usage caveats
- frontmatter imports not working for any format supported by a resource plugin
- ESM only configuration for PostCSS plugin
- standardize on Greenwood config as single source for
prerender
behavior for all renderer plugins - CSS bundling optimization not handling transitive relative
url(...)
references - update init scaffolding to use unified website Discord link
- unable to resolve packages with a nested package.json
- intermittent
Response.clone: Body has already been consumed
error from the dev server - frontmatter content breaking graph data parsing in SSR pages
- none optimization setting leads to broken resource requests in production builds
- getting a
Cannot read properties of null (reading 'rawAttrs')
error - data client not working on production builds (when not using
prerender
option) - PostCSS plugin breaks bundling of SSR CSS-based import attributes
- SSR pages are not have resource plugin optimization lifecycles applied
- Upgrade minimum NodeJS LTS version
- bundling for CSS relative node_modules based
url
references breaks - migrate to register function for NodeJS custom imports
- allow for customizable serverless nodejs runtime version for Vercel adapter
- Better support for (GitHub flavored) Markdown
- fix missing runtime key for API routes when using Vercel adapter
- import map generation not finding package.json for some libraries like tslib (when recursively segmenting entry point)
- rollup bundling failing trying to resolve directories
- log when API routes are being bundled
- import map generation cache and dedupe optimizations
- export map sub condition object keys with a wildcard are not resolving in the browser (condition not getting expanded)
- better sanitize Rollup importer for when resolving user workspace resources
- escaped HTML entities in markdown content are not being honored when prerendering Light DOM HTML
- improve import map generation diagnostics
- bump to latest version of puppeteer
- upgrade to WCC v0.16.0
Breaking Changes
NodeJS version
The new minimum versions for NodeJS are as follows
^18.20.5
^20.10.0
^22.12.0
Import Maps (during development)
With this new version of Greenwood, our honoring of the exports spec will now be a lot more compliant and complete, but may (unintentionally) "break" some packages you might be using. In particular, one case observed where this breaks is Lit v2, which as of v3, now supports exports.
If you find any issues after upgrading, please review any diagnostics emitted by Greenwood and review the docs on our website, or check to see if there are newer versions of your package available. If you're still stuck, please reach out to us on Discord or in this GitHub discussion.
Markdown
As part of this release, we update all unified related plugins to latest. This introduced a couple user-facing breaking changes:
- The
markdown.settings
configuration option option is longer supported as it's no longer supported by remark-parse - GFM (GitHub flavored markdown) was removed from remark, so make sure to bring your own, like remark-gfm, especially for things like tables
process.env.NODE_ENV
Prior to this release, Greenwood had included a behavior that would automatically replace instances of process.env.NODE_ENV
in browser build output, but this was mostly for libraries like Redux that were not properly isomorphic. (process
is not supported in browsers!)
Ideally packages you use should acknowledge this already, but if you still run into packages that make this assumption, you can re-recreate this substitution behavior using a Greenwood plugin
// greenwood.config.js
import { ResourceInterface } from '@greenwood/cli/src/lib/resource-interface.js';
class ProcessEnvReplaceResource extends ResourceInterface {
constructor(compilation) {
super();
this.compilation = compilation;
}
async shouldIntercept(url) {
// your custom condition goes here
return url.pathname.endsWith('redux.mjs');
}
async intercept(url, request, response) {
const body = await response.text();
const env = process.env.__GWD_COMMAND__ === 'develop' ? 'development' : 'production';
const contents = body.replace(/process.env.NODE_ENV/g, `"${env}"`);
return new Response(contents, {
headers: new Headers({
'Content-Type': 'text/javascript',
})
});
}
}
export default {
// ...
plugins: [{
type: 'resource',
name: 'process-env-replace',
provider: (compilation) => new ProcessEnvReplaceResource(compilation)
}]
}
WCC
There were a couple minor breaking changes in WCC, so please review the release notes to account for any changes that may impact your usage.
Node Modules
Going forward, the recommended pattern for referencing assets from your node_modules folder (that are not bare module ESM specifiers) will be to start all paths with /node_modules/
. This will ensure Greenwood knows to use import.meta.resolve
to find and lookup your dependency where ever it is installed based on your package managers.
Examples
@import "/node_modules/font-awesome/css/font-awesome.css";
@import "/node_modules/bootstrap/dist/css/bootstrap.css";
<script type="module" src="/node_modules/@shoelace-style/shoelace/dist/shoelace.js"></script>
PostCSS Plugin
Greenwood know supports only needing to have one PostCSS config for your project. So with this release, you can now
- Rename postcss.config.mjs -> postcss.config.js
- Delete postcss.config.cjs
If you're using Storybook <= 7, rename your postcss.config.cjs -> .postcssrc.js instead
prerender
configuration and renderer plugins
Although Greenwood has a "top-level" configuration setting for prerender
in greenwood.config.js, some renderer plugins also exposed a prerender
option through their plugin configuration. As per #1343 , having multiple options for the same thing is confusing, additionally since there can only ever be one renderer at a time, so it's not like there is an option to mix and match.
So going forward, prerender
configuration must be explicitly set in your greenwood.config.js. All relevant Greenwood plugins will just ignore the option if passed in to a plugins options.
Custom Loaders
Custom loaders now use the register API and requires at least NodeJS ^20.10.0
or ^22.12.0
and using the --import
flag
# before
$ node --loader ./node_modules/@greenwood/cli/src/loader.js ./node_modules/@greenwood/cli/src/index.js <command>
# after
$ node --import @greenwood/cli/src/register.js ./node_modules/@greenwood/cli/src/index.js <command>
Vercel Adapter
In addition to allowing the runtime of serverless functions to be configurable, the default version of NodeJS set will be 20.x
Known Issues
N / A