feat: attach Svelte major version info to window global (#8761)

Can be opt out by setting discloseVersion to false

---------

Co-authored-by: Simon H <5968653+dummdidumm@users.noreply.github.com>
Co-authored-by: Ben McCann <322311+benmccann@users.noreply.github.com>
pull/8772/head
gtmnayan 2 years ago committed by GitHub
parent 03942162f8
commit 5702142d9e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -0,0 +1,5 @@
---
'svelte': patch
---
feat: add version info to `window`. You can opt out by setting `discloseVersion` to `false` in the compiler options

@ -1,3 +1,7 @@
<script>
import Counter from "./lib/Counter.svelte";
</script>
<div> <div>
Hello world! Hello world!
</div> </div>

@ -56,6 +56,9 @@
"types": "./types/index.d.ts", "types": "./types/index.d.ts",
"import": "./src/runtime/store/index.js" "import": "./src/runtime/store/index.js"
}, },
"./internal/disclose-version": {
"import": "./src/runtime/internal/disclose-version/index.js"
},
"./transition": { "./transition": {
"types": "./types/index.d.ts", "types": "./types/index.d.ts",
"import": "./src/runtime/transition/index.js" "import": "./src/runtime/transition/index.js"

@ -13,5 +13,6 @@ fs.writeFileSync(
* @type {string} * @type {string}
*/ */
export const VERSION = '${pkg.version}'; export const VERSION = '${pkg.version}';
export const PUBLIC_VERSION = '${pkg.version.split('.')[0]}';
` `
); );

@ -30,7 +30,8 @@ const valid_options = [
'loopGuardTimeout', 'loopGuardTimeout',
'preserveComments', 'preserveComments',
'preserveWhitespace', 'preserveWhitespace',
'cssHash' 'cssHash',
'discloseVersion'
]; ];
const valid_css_values = [true, false, 'injected', 'external', 'none']; const valid_css_values = [true, false, 'injected', 'external', 'none'];
const regex_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/; const regex_valid_identifier = /^[a-zA-Z_$][a-zA-Z_$0-9]*$/;
@ -112,6 +113,10 @@ function validate_options(options, warnings) {
throw new Error(`Invalid namespace '${namespace}'`); throw new Error(`Invalid namespace '${namespace}'`);
} }
} }
if (options.discloseVersion == undefined) {
options.discloseVersion = true;
}
} }
/** /**

@ -604,5 +604,17 @@ export default function dom(component, options) {
); );
} }
} }
if (options.discloseVersion === true) {
component.imports.unshift({
type: 'ImportDeclaration',
specifiers: [],
source: {
type: 'Literal',
value: `${options.sveltePath ?? 'svelte'}/internal/disclose-version`
}
});
}
return { js: flatten(body), css }; return { js: flatten(body), css };
} }

@ -344,6 +344,12 @@ export interface CompileOptions {
* @default false * @default false
*/ */
preserveWhitespace?: boolean; preserveWhitespace?: boolean;
/**
* If `true`, exposes the Svelte major version on the global `window` object in the browser.
*
* @default true
*/
discloseVersion?: boolean;
} }
export interface ParserOptions { export interface ParserOptions {

@ -0,0 +1,5 @@
import { PUBLIC_VERSION } from '../../../shared/version.js';
if (typeof window !== 'undefined')
// @ts-ignore
(window.__svelte || (window.__svelte = { v: new Set() })).v.add(PUBLIC_VERSION);

@ -7,3 +7,4 @@
* @type {string} * @type {string}
*/ */
export const VERSION = '4.0.0-next.2'; export const VERSION = '4.0.0-next.2';
export const PUBLIC_VERSION = '4';

@ -147,6 +147,7 @@ export function create_loader(compileOptions, cwd) {
// any imported Svelte components as well. A few edge cases aren't handled but also // any imported Svelte components as well. A few edge cases aren't handled but also
// currently unused in the tests, for example `export * from`and live bindings. // currently unused in the tests, for example `export * from`and live bindings.
let transformed = compiled.js.code let transformed = compiled.js.code
.replace(/^import ['"]([^'"]+)['"]/gm, 'await __import("$1")')
.replace( .replace(
/^import \* as (\w+) from ['"]([^'"]+)['"];?/gm, /^import \* as (\w+) from ['"]([^'"]+)['"];?/gm,
'const $1 = await __import("$2");' 'const $1 = await __import("$2");'

@ -33,7 +33,12 @@ describe('js-output', () => {
let actual; let actual;
try { try {
const options = Object.assign({}, config.options || {}); const options = Object.assign(
{
discloseVersion: false
},
config.options || {}
);
actual = svelte actual = svelte
.compile(input, options) .compile(input, options)

@ -6,8 +6,7 @@ import * as svelte from 'svelte/compiler';
import { afterAll, assert, beforeAll, describe, it } from 'vitest'; import { afterAll, assert, beforeAll, describe, it } from 'vitest';
import { pretty_print_browser_assertion, try_load_config } from '../helpers.js'; import { pretty_print_browser_assertion, try_load_config } from '../helpers.js';
const internal = path.resolve('src/runtime/internal/index.js'); const assert_file = path.resolve(__dirname, 'assert.js');
const index = path.resolve('src/runtime/index.js');
/** @type {import('@playwright/test').Browser} */ /** @type {import('@playwright/test').Browser} */
let browser; let browser;
@ -62,9 +61,7 @@ async function run_browser_test(dir) {
alias: { alias: {
__MAIN_DOT_SVELTE__: path.resolve(__dirname, 'samples', dir, 'main.svelte'), __MAIN_DOT_SVELTE__: path.resolve(__dirname, 'samples', dir, 'main.svelte'),
__CONFIG__: path.resolve(__dirname, 'samples', dir, '_config.js'), __CONFIG__: path.resolve(__dirname, 'samples', dir, '_config.js'),
'assert.js': path.resolve(__dirname, 'assert.js'), 'assert.js': assert_file
'svelte/internal': internal,
svelte: index
}, },
plugins: [ plugins: [
{ {
@ -169,9 +166,7 @@ async function run_custom_elements_test(dir) {
entryPoints: [`${cwd}/test.js`], entryPoints: [`${cwd}/test.js`],
write: false, write: false,
alias: { alias: {
'assert.js': path.resolve(__dirname, 'assert.js'), 'assert.js': assert_file
'svelte/internal': internal,
svelte: index
}, },
plugins: [ plugins: [
{ {

Loading…
Cancel
Save