Skip to content

Commit 5d1837b

Browse files
authored
fix(compiler): log warning for missing name/namespace (#4825)
1 parent c4218fc commit 5d1837b

File tree

5 files changed

+76
-4
lines changed

5 files changed

+76
-4
lines changed
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright (c) 2024, salesforce.com, inc.
3+
* All rights reserved.
4+
* SPDX-License-Identifier: MIT
5+
* For full license text, see the LICENSE file in the repo root or https://opensource.org/licenses/MIT
6+
*/
7+
import { afterEach, beforeEach, expect, vi, test } from 'vitest';
8+
import { transformSync } from '@babel/core';
9+
import plugin from '../index';
10+
11+
let spy;
12+
13+
beforeEach(() => {
14+
spy = vi.spyOn(console, 'warn');
15+
});
16+
17+
afterEach(() => {
18+
spy!.mockReset();
19+
});
20+
21+
test('warns on missing name/namespace', () => {
22+
const source = `
23+
import { LightningElement } from 'lwc';
24+
export default class extends LightningElement {};
25+
`;
26+
27+
const { code } = transformSync(source, {
28+
babelrc: false,
29+
configFile: false,
30+
filename: `foo.js`,
31+
plugins: [
32+
[
33+
plugin,
34+
{
35+
namespace: '',
36+
name: '',
37+
},
38+
],
39+
],
40+
})!;
41+
42+
// compilation works successfully
43+
expect(code).toBeTypeOf('string');
44+
45+
expect(spy!).toHaveBeenCalledOnce();
46+
expect(spy!).toHaveBeenCalledWith(
47+
'The namespace and name should both be non-empty strings. You may get unexpected behavior at runtime. Found: namespace="" and name=""'
48+
);
49+
});

packages/@lwc/babel-plugin-component/src/types.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ export interface LwcBabelPluginOptions {
1717
loader?: string;
1818
strictSpecifier?: boolean;
1919
};
20-
namespace?: string;
21-
name?: string;
20+
namespace: string;
21+
name: string;
2222
instrumentation?: InstrumentationObject;
2323
apiVersion?: number;
2424
}

packages/@lwc/compiler/src/options.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,9 +95,9 @@ export interface DynamicImportConfig {
9595
*/
9696
export interface TransformOptions {
9797
/** The name of the component. For example, the name in `<my-component>` is `"component"`. */
98-
name?: string;
98+
name: string;
9999
/** The namespace of the component. For example, the namespace in `<my-component>` is `"my"`. */
100-
namespace?: string;
100+
namespace: string;
101101
/** @deprecated Ignored by compiler. */
102102
stylesheetConfig?: StylesheetConfig;
103103
// TODO [#5031]: Unify dynamicImports and experimentalDynamicComponent options

packages/@lwc/rollup-plugin/src/index.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,17 @@ export default function lwc(pluginOptions: RollupLwcOptions = {}): Plugin {
334334
// a '/' regardless of Windows vs Unix, since it comes from the Rollup `id`
335335
specifier?.split('/') ?? path.dirname(filename).split('/').slice(-2);
336336

337+
/* v8 ignore next */
338+
if (!namespace || !name) {
339+
// TODO [#4824]: Make this an error rather than a warning
340+
this.warn(
341+
'The component namespace and name could not be determined from the specifier ' +
342+
JSON.stringify(specifier) +
343+
' or filename ' +
344+
JSON.stringify(filename)
345+
);
346+
}
347+
337348
const apiVersionToUse = getAPIVersionFromNumber(apiVersion);
338349

339350
const { code, map, warnings } = transformSync(src, filename, {

packages/@lwc/shared/src/custom-element.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@
1515
* @returns component tag name
1616
*/
1717
export function generateCustomElementTagName(namespace: string = '', name: string = '') {
18+
if (!namespace || !name) {
19+
// TODO [#4824]: Make this an error rather than a warning
20+
// eslint-disable-next-line no-console
21+
console.warn(
22+
'The namespace and name should both be non-empty strings. ' +
23+
'You may get unexpected behavior at runtime. ' +
24+
'Found: namespace=' +
25+
JSON.stringify(namespace) +
26+
' and name=' +
27+
JSON.stringify(namespace)
28+
);
29+
}
1830
const kebabCasedName = name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
1931
return `${namespace}-${kebabCasedName}`;
2032
}

0 commit comments

Comments
 (0)