Repository: sveltejs/svelte (JavaScript)
Date: 2018-12-29 15:59:01+00:00
Task type: Bug Fix

Issue:
Implicit props can break stuff
This component...

```html
<p>process.env.BASEURL: {process.env.BASEURL}</p>
```

...doesn't work, whereas this one does:

```html
<script>
  // ...
</script>

<p>process.env.BASEURL: {process.env.BASEURL}</p>
```

That's because `process` is assumed to be an implicit prop in the first case. Whitelisted globals are ignored, so `<p>{Math.max(1, 2)</p>` works just fine, but I wonder if we should have a fallback in place for unknown globals.


Issue discussion:
What's the difference between an unknown global and an implicit prop? These seem impossible to distinguish.
My thinking is something like this should work:

```js
const { process = global.process } = $$props;
```
Oh, gotcha, so the compiler _wouldn't_ distinguish between them. A runtime fallback makes sense then.

Solution patch:
diff --git a/src/compile/render-dom/index.ts b/src/compile/render-dom/index.ts
--- a/src/compile/render-dom/index.ts
+++ b/src/compile/render-dom/index.ts
@@ -279,7 +279,7 @@ export default function dom(
 
 	const user_code = component.javascript || (
 		component.ast.js.length === 0 && filtered_props.length > 0
-			? `let { ${filtered_props.map(x => x.name === x.as ? x.as : `${x.as}: ${x.name}`).join(', ')} } = $$props;`
+			? `let { ${filtered_props.map(x => x.name).join(', ')} } = $$props;`
 			: null
 	);
 
diff --git a/src/utils/globalWhitelist.ts b/src/utils/globalWhitelist.ts
--- a/src/utils/globalWhitelist.ts
+++ b/src/utils/globalWhitelist.ts
@@ -19,6 +19,7 @@ export default new Set([
 	'Object',
 	'parseFloat',
 	'parseInt',
+	'process',
 	'Promise',
 	'RegExp',
 	'Set',


Test patch:
diff --git a/test/runtime/index.js b/test/runtime/index.js
--- a/test/runtime/index.js
+++ b/test/runtime/index.js
@@ -126,7 +126,9 @@ describe("runtime", () => {
 
 					global.window = window;
 
-					// Put the constructor on window for testing
+					if (config.before_test) config.before_test();
+
+					// Put things we need on window for testing
 					window.SvelteComponent = SvelteComponent;
 
 					const target = window.document.querySelector("main");
@@ -208,6 +210,8 @@ describe("runtime", () => {
 					}
 
 					flush();
+
+					if (config.after_test) config.after_test();
 				});
 		});
 	}
diff --git a/test/runtime/samples/globals-accessible-directly-process/_config.js b/test/runtime/samples/globals-accessible-directly-process/_config.js
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/globals-accessible-directly-process/_config.js
@@ -0,0 +1,11 @@
+export default {
+	html: '<h1>Hello world!</h1>',
+
+	before_test() {
+		process.env.TMP_VAR = 'world';
+	},
+
+	after_test() {
+		delete process.env.TMP_VAR;
+	}
+};
diff --git a/test/runtime/samples/globals-accessible-directly-process/main.html b/test/runtime/samples/globals-accessible-directly-process/main.html
new file mode 100644
--- /dev/null
+++ b/test/runtime/samples/globals-accessible-directly-process/main.html
@@ -0,0 +1 @@
+<h1>Hello {process.env.TMP_VAR}!</h1>
\ No newline at end of file
diff --git a/test/server-side-rendering/index.js b/test/server-side-rendering/index.js
--- a/test/server-side-rendering/index.js
+++ b/test/server-side-rendering/index.js
@@ -114,6 +114,8 @@ describe("ssr", () => {
 			require("../../register")(compileOptions);
 
 			try {
+				if (config.before_test) config.before_test();
+
 				const Component = require(`../runtime/samples/${dir}/main.html`).default;
 				const { html } = Component.render(config.props, {
 					store: (config.store !== true) && config.store
@@ -124,6 +126,8 @@ describe("ssr", () => {
 				} else if (config.html) {
 					assert.htmlEqual(html, config.html);
 				}
+
+				if (config.after_test) config.after_test();
 			} catch (err) {
 				if (config.error) {
 					if (typeof config.error === 'function') {