Skip to content

Commit 47c4ccb

Browse files
fix(compiler): update package.json validation for the 'module' field (#3475)
This updates the validation around the `module` field in `package.json` to take the configured output targets into account. In particular, for `DIST_CUSTOM_ELEMENTS_BUNDLE` it should be something like `dist/index.js`, whereas for `DIST_CUSTOM_ELEMENTS` it should be something like `dist/components/index.js`.
1 parent 65f5275 commit 47c4ccb

File tree

3 files changed

+254
-49
lines changed

3 files changed

+254
-49
lines changed

src/compiler/types/tests/validate-package-json.spec.ts

Lines changed: 72 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@ import type * as d from '@stencil/core/declarations';
22
import { mockBuildCtx, mockCompilerCtx, mockConfig } from '@stencil/core/testing';
33
import * as v from '../validate-build-package-json';
44
import path from 'path';
5-
import { DIST_CUSTOM_ELEMENTS_BUNDLE } from '../../output-targets/output-utils';
5+
import { DIST_COLLECTION, DIST_CUSTOM_ELEMENTS, DIST_CUSTOM_ELEMENTS_BUNDLE } from '../../output-targets/output-utils';
6+
import { normalizePath } from '../../../utils/normalize-path';
67

78
describe('validate-package-json', () => {
89
let config: d.Config;
@@ -84,11 +85,11 @@ describe('validate-package-json', () => {
8485
config.outputTargets = [];
8586
compilerCtx.fs.writeFile(path.join(root, 'dist', 'index.js'), '');
8687
buildCtx.packageJson.module = 'dist/index.js';
87-
v.validateModule(config, compilerCtx, buildCtx, collectionOutputTarget);
88+
await v.validateModule(config, compilerCtx, buildCtx);
8889
expect(buildCtx.diagnostics).toHaveLength(0);
8990
});
9091

91-
it('validate custom elements module', async () => {
92+
it('validate custom elements bundle module', async () => {
9293
config.outputTargets = [
9394
{
9495
type: DIST_CUSTOM_ELEMENTS_BUNDLE,
@@ -97,25 +98,86 @@ describe('validate-package-json', () => {
9798
];
9899
compilerCtx.fs.writeFile(path.join(root, 'dist', 'index.js'), '');
99100
buildCtx.packageJson.module = 'custom-elements/index.js';
100-
v.validateModule(config, compilerCtx, buildCtx, collectionOutputTarget);
101+
await v.validateModule(config, compilerCtx, buildCtx);
101102
expect(buildCtx.diagnostics).toHaveLength(0);
102103
});
103104

105+
it('validates a valid custom elements module', async () => {
106+
config.outputTargets = [
107+
{
108+
type: DIST_CUSTOM_ELEMENTS,
109+
dir: path.join(root, 'dist'),
110+
},
111+
];
112+
buildCtx.packageJson.module = 'dist/components/index.js';
113+
await v.validateModule(config, compilerCtx, buildCtx);
114+
expect(buildCtx.diagnostics).toHaveLength(0);
115+
});
116+
117+
it('errors on an invalid custom elements module', async () => {
118+
config.outputTargets = [
119+
{
120+
type: DIST_CUSTOM_ELEMENTS,
121+
dir: path.join(root, 'dist'),
122+
},
123+
];
124+
buildCtx.packageJson.module = 'dist/index.js';
125+
await v.validateModule(config, compilerCtx, buildCtx);
126+
expect(buildCtx.diagnostics).toHaveLength(1);
127+
const [diagnostic] = buildCtx.diagnostics;
128+
expect(diagnostic.level).toBe('warn');
129+
expect(diagnostic.messageText).toBe(
130+
`package.json "module" property is set to "dist/index.js". It's recommended to set the "module" property to: ./dist/components/index.js`
131+
);
132+
});
133+
104134
it('missing dist module', async () => {
105135
config.outputTargets = [];
106-
v.validateModule(config, compilerCtx, buildCtx, collectionOutputTarget);
136+
await v.validateModule(config, compilerCtx, buildCtx);
107137
expect(buildCtx.diagnostics).toHaveLength(1);
138+
const [diagnostic] = buildCtx.diagnostics;
139+
expect(diagnostic.level).toBe('warn');
140+
expect(diagnostic.messageText).toBe('package.json "module" property is required when generating a distribution.');
108141
});
109142

110-
it('missing dist module, but has custom elements output', async () => {
111-
config.outputTargets = [
112-
{
143+
it.each<{
144+
ot: d.OutputTarget;
145+
path: string;
146+
}>([
147+
{
148+
ot: {
113149
type: DIST_CUSTOM_ELEMENTS_BUNDLE,
114150
dir: path.join(root, 'custom-elements'),
115151
},
116-
];
117-
v.validateModule(config, compilerCtx, buildCtx, collectionOutputTarget);
152+
path: 'custom-elements/index.js',
153+
},
154+
{
155+
ot: {
156+
type: DIST_CUSTOM_ELEMENTS,
157+
dir: path.join(root, 'dist'),
158+
},
159+
path: 'dist/components/index.js',
160+
},
161+
{
162+
ot: {
163+
type: DIST_COLLECTION,
164+
dir: path.join(root, 'dist'),
165+
collectionDir: 'dist/collection',
166+
},
167+
path: 'dist/index.js',
168+
},
169+
])('errors on missing module w/ $ot.type, suggests $path', async ({ ot, path }) => {
170+
config.outputTargets = [ot];
171+
buildCtx.packageJson.module = undefined;
172+
await v.validateModule(config, compilerCtx, buildCtx);
118173
expect(buildCtx.diagnostics).toHaveLength(1);
174+
const [diagnostic] = buildCtx.diagnostics;
175+
expect(diagnostic.level).toBe('warn');
176+
expect(diagnostic.messageText).toBe(
177+
`package.json "module" property is required when generating a distribution. It's recommended to set the "module" property to: ${normalizePath(
178+
path
179+
)}`
180+
);
119181
});
120182
});
121183

0 commit comments

Comments
 (0)