Skip to content

Commit

Permalink
add support for custom named exports (#452)
Browse files Browse the repository at this point in the history
  • Loading branch information
FredKSchott committed Jun 9, 2020
1 parent 97f6c1f commit 35112ac
Show file tree
Hide file tree
Showing 10 changed files with 62 additions and 7 deletions.
6 changes: 5 additions & 1 deletion docs/05-configuration.md
Expand Up @@ -93,11 +93,15 @@ $ snowpack dev --no-bundle
- **`alias`** | `{[mapFromPackageName: string]: string}`
- Alias an installed package name. This applies to imports within your application and within your installed dependency graph.
- Example: `"alias": {"react": "preact/compat", "react-dom": "preact/compat"}`
- **`namedExports`** | `string[]`
- Legacy Common.js (CJS) packages should only be imported by the default import (Example: `import reactTable from 'react-table'`)
- But, some packages use named exports in their documentation, which can cause confusion for users. (Example: `import {useTable} from 'react-table'`)
- You can enable "fake/synthetic" named exports for Common.js package by adding the package name under this configuration.
- Example: `"namedExports": ["react-table"]`
- **`rollup`**
- Snowpack uses Rollup internally to install your packages. This `rollup` config option gives you deeper control over the internal rollup configuration that we use.
- **`rollup.plugins`** - Specify [Custom Rollup plugins](#installing-non-js-packages) if you are dealing with non-standard files.
- **`rollup.dedupe`** - If needed, deduplicate multiple versions/copies of a packages to a single one. This helps prevent issues with some packages when multiple versions are installed from your node_modules tree. See [rollup-plugin-node-resolve](https://github.com/rollup/plugins/tree/master/packages/node-resolve#usage) for more documentation.
- **`rollup.namedExports`** - **DEPRECATED** Rollup has gotten good enough at Common.js<->ESM interop that it no longer needs this fallback, and will fail if you pass it. If you're currently using it, it should be safe to remove.

#### Dev Options

Expand Down
12 changes: 9 additions & 3 deletions src/commands/install.ts
Expand Up @@ -48,14 +48,16 @@ class ErrorWithHint extends Error {
// import React from 'react';
// But, some large projects use named exports in their documentation:
// import {useState} from 'react';
// Note that this is not a problem for ESM packages, only CJS.
//
// We use "/index.js here to match the official package, but not any ESM aliase packages
// that the user may have installed instead (ex: react-esm).
const CJS_PACKAGES_TO_AUTO_DETECT = [
'react/index.js',
'react-dom/index.js',
'react-table/index.js',
'react-is/index.js',
'prop-types/index.js',
'scheduler/index.js',
'react-table',
];

const cwd = process.cwd();
Expand Down Expand Up @@ -335,7 +337,11 @@ export async function install(
rollupPluginCommonjs({
extensions: ['.js', '.cjs'], // Default: [ '.js' ]
}),
rollupPluginWrapInstallTargets(!!isTreeshake, CJS_PACKAGES_TO_AUTO_DETECT, installTargets),
rollupPluginWrapInstallTargets(
!!isTreeshake,
[...CJS_PACKAGES_TO_AUTO_DETECT, ...config.installOptions.namedExports],
installTargets,
),
rollupPluginDependencyStats((info) => (dependencyStats = info)),
...userDefinedRollup.plugins, // load user-defined plugins last
rollupPluginCatchUnresolved(),
Expand Down
6 changes: 4 additions & 2 deletions src/config.ts
Expand Up @@ -108,6 +108,7 @@ export interface SnowpackConfig {
sourceMap?: boolean | 'inline';
externalPackage: string[];
alias: {[key: string]: string};
namedExports: string[];
rollup: {
plugins: RollupPlugin[]; // for simplicity, only Rollup plugins are supported for now
dedupe?: string[];
Expand Down Expand Up @@ -136,6 +137,7 @@ const DEFAULT_CONFIG: Partial<SnowpackConfig> = {
installTypes: false,
env: {},
alias: {},
namedExports: [],
rollup: {
plugins: [],
dedupe: [],
Expand Down Expand Up @@ -532,14 +534,14 @@ function validateConfigAgainstV1(rawConfig: any, cliFlags: any) {
}
if (rawConfig.namedExports) {
handleDeprecatedConfigError(
'[Snowpack v1 -> v2] `namedExports` was removed in the latest version of Rollup, and should no longer be needed.',
'[Snowpack v1 -> v2] `rollup.namedExports` is no longer required. See also: installOptions.namedExports',
);
}
if (rawConfig.installOptions?.rollup?.namedExports) {
delete rawConfig.installOptions.rollup.namedExports;
console.error(
chalk.yellow(
'[Snowpack v2.3.0] `namedExports` was removed in the latest version of Rollup, and is now safe to remove from your config.',
'[Snowpack v2.3.0] `rollup.namedExports` is no longer required. See also: installOptions.namedExports',
),
);
}
Expand Down
4 changes: 3 additions & 1 deletion src/rollup-plugin-wrap-install-targets.ts
Expand Up @@ -33,7 +33,9 @@ export function rollupPluginWrapInstallTargets(
const installTargetsByFile: {[loc: string]: InstallTarget[]} = {};

function isAutoDetect(normalizedFileLoc: string) {
return autoDetectPackageExports.some((p) => normalizedFileLoc.includes(`node_modules/${p}`));
return autoDetectPackageExports.some((p) =>
normalizedFileLoc.includes(`node_modules/${p}${p.endsWith('index.js') ? '' : '/'}`),
);
}
return {
name: 'snowpack:wrap-install-targets',
Expand Down
@@ -0,0 +1,5 @@
{
"imports": {
"mock-test-package": "./mock-test-package.js"
}
}
@@ -0,0 +1,8 @@
var entrypoint = {
export1: 'foo',
export2: 'bar',
};
var entrypoint_1 = entrypoint.export1;
var entrypoint_2 = entrypoint.export2;

export { entrypoint_1 as export1, entrypoint_2 as export2 };
4 changes: 4 additions & 0 deletions test/integration/config-named-exports/expected-output.txt
@@ -0,0 +1,4 @@
- snowpack installing...
✔ snowpack install complete.
⦿ web_modules/ size gzip brotli
└─ mock-test-package.js XXXX KB XXXX KB XXXX KB

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions test/integration/config-named-exports/package.json
@@ -0,0 +1,15 @@
{
"description": "Handle installOptions.namedExports",
"scripts": {
"TEST": "node ../../../pkg/dist-node/index.bin.js"
},
"snowpack": {
"install": ["mock-test-package"],
"installOptions": {
"namedExports": ["mock-test-package"]
}
},
"dependencies": {
"mock-test-package": "^1.0.0"
}
}

0 comments on commit 35112ac

Please sign in to comment.