diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0a4b7ae56f..bc311958dd 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,8 @@
# Svelte changelog
-## Unreleased
+## 3.30.1
+* Support consuming decoded sourcemaps as created by the `source-map` library's `SourceMapGenerator` ([#5722](https://github.com/sveltejs/svelte/issues/5722))
* Actually export `hasContext` ([#5726](https://github.com/sveltejs/svelte/issues/5726))
## 3.30.0
diff --git a/package-lock.json b/package-lock.json
index 9573556825..885b206b6a 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1,6 +1,6 @@
{
"name": "svelte",
- "version": "3.30.0",
+ "version": "3.30.1",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
diff --git a/package.json b/package.json
index 10b35d6706..688819c614 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "svelte",
- "version": "3.30.0",
+ "version": "3.30.1",
"description": "Cybernetically enhanced web apps",
"module": "index.mjs",
"main": "index",
diff --git a/site/content/blog/2017-08-07-the-easiest-way-to-get-started.md b/site/content/blog/2017-08-07-the-easiest-way-to-get-started.md
index 9d4c661615..5fed4b347c 100644
--- a/site/content/blog/2017-08-07-the-easiest-way-to-get-started.md
+++ b/site/content/blog/2017-08-07-the-easiest-way-to-get-started.md
@@ -55,6 +55,6 @@ Once you've tinkered a bit and understood how everything fits together, you can
npx degit your-name/template my-new-project
```
-And that's it! Do `npm run build` to create a production-ready version of your app, and check the project template's [README](https://github.com/sveltejs/template/blob/master/README.md) for instructions on how to easily deploy your app to the web with [Now](https://zeit.co/now) or [Surge](http://surge.sh/).
+And that's it! Do `npm run build` to create a production-ready version of your app, and check the project template's [README](https://github.com/sveltejs/template/blob/master/README.md) for instructions on how to easily deploy your app to the web with [Vercel](https://vercel.com) or [Surge](http://surge.sh/).
You're not restricted to using Rollup — there are also integrations for [webpack](https://github.com/sveltejs/svelte-loader), [Browserify](https://github.com/tehshrike/sveltify) and others, or you can use the [Svelte CLI](https://github.com/sveltejs/svelte-cli) (Update from 2019: with Svelte 3 the CLI was deprecated and we now use [sirv-cli](https://www.npmjs.com/package/sirv-cli) in our template. Feel free to use whatever tool you like!) or the [API](https://github.com/sveltejs/svelte/tree/v2#api) directly. If you make a project template using one of these tools, please share it with the [Svelte Discord chatroom](chat), or via [@sveltejs](https://twitter.com/sveltejs) on Twitter!
diff --git a/site/content/blog/2020-12-01-whats-new-in-svelte-december-2020.md b/site/content/blog/2020-12-01-whats-new-in-svelte-december-2020.md
new file mode 100644
index 0000000000..5edaf31311
--- /dev/null
+++ b/site/content/blog/2020-12-01-whats-new-in-svelte-december-2020.md
@@ -0,0 +1,71 @@
+---
+title: What's new in Svelte: December 2020
+description: Better tooling, export maps and improvements to slots and context
+author: Daniel Sandoval
+authorURL: https://desandoval.net
+---
+
+It's the last "What's new in Svelte" of the year and there's lots to celebrate! This month's coverage includes updates from `rollup-plugin-svelte`, `Sapper` and `SvelteKit` and a bunch of showcases from the Svelte community!
+
+## New features & impactful bug fixes
+
+1. `$$props`, `$$restProps`, and `$$slots` are all now supported in custom web components (**3.29.5**, [Example](https://svelte.dev/repl/ad8e6f39cd20403dacd1be84d71e498d?version=3.29.5)) and `slot` components now support spread props: `` (**3.30.0**)
+2. A new `hasContext` lifecycle function makes it easy to check whether a `key` has been set in the context of a parent component (**3.30.0** & **3.30.1**, [Docs](https://svelte.dev/docs#hasContext))
+3. `SvelteComponent` is now typed which makes it easier to add typed classes that extend base Svelte Components. Component library and framework authors rejoice! An example: `export class YourComponent extends SvelteComponent<{aProp: boolean}, {click: MouseEvent}, {default: {aSlot: string}}> {}` (**3.30.0**, [RFC](https://github.com/sveltejs/rfcs/pull/37))
+4. Transitions within `{:else}` blocks should now complete successfully (**3.29.5**, [Example](https://svelte.dev/repl/49cef205e5da459594ef2eafcbd41593?version=3.29.5))
+5. Svelte now includes an export map, which explicitly states which files can be imported from its npm package (**3.29.5** with some fixes in **3.29.6**, **3.29.7** and **3.30.0**)
+6. `rollup-plugin-svelte` had a new [7.0.0 release](https://github.com/sveltejs/rollup-plugin-svelte/blob/master/CHANGELOG.md). The biggest change is that the `css` option was removed. Users who were using that option should add another plugin like `rollup-plugin-css-only` as demonstrated [in the template](https://github.com/sveltejs/template/blob/5b1135c286f7a649daa99825a077586655051649/rollup.config.js#L48)
+
+
+## What's going on in Sapper?
+Lots of new TypeScript definition improvements to make editing Sapper apps even easier! CSS for dynamic imports also should now work in `client.js` files. (Unreleased)
+
+## What's the deal with SvelteKit?
+We're glad you asked! If you didn't catch Rich's blog post from early last month, [you can find it here](https://svelte.dev/blog/whats-the-deal-with-sveltekit)!
+
+For all the features and bugfixes see the CHANGELOGs for [Svelte](https://github.com/sveltejs/svelte/blob/master/CHANGELOG.md) and [Sapper](https://github.com/sveltejs/sapper/blob/master/CHANGELOG.md).
+
+---
+
+## Community Showcase
+
+**Apps & Sites**
+- [narration.studio](https://narration.studio/) (Chrome Only) is an automatic in-browser audio recording & editing platform for voice over narration.
+- [Vippet](https://vippet.netlify.app/) is a video recording and editing tool for the browser.
+- [Pattern Monster](https://pattern.monster/) is a simple online pattern generator to create repeatable SVG patterns.
+- [Plant-based diets](https://planetbaseddiets.panda.org/) is a website from the World Wildlife Foundation (WWF) built with Svelte.
+- [johnells.se](https://www.johnells.se/) is a Swedish fashion e-commerce site, built with [Crown](https://crownframework.com/) - a Svelte-powered framework.
+- [sentence-length](https://sentence-length.netlify.app/) is a learning and analysis tool to show how some authors play with different lengths, while others stick with one.
+- [svelte-presenter](https://github.com/stephane-vanraes/svelte-presenter) lets you quickly make good looking presentations using Svelte and mdsvex.
+
+**Demos**
+- [u/loopcake got SSR working in Java Spring Boot](https://www.reddit.com/r/sveltejs/comments/jkh5up/svelte_ssr_but_its_java_spring_boot_and_its_native/) for all the Java shops out there looking to render Svelte server-side.
+- [svelte-liquid-swipe](https://github.com/tncrazvan/svelte-liquid-swipe) shows off a fancy interaction pattern using svg paths.
+- [Crossfade Link Animation](https://svelte.dev/repl/7f68e148caf04b2787bb6f296208f870?version=3.29.7) demonstrates how to animate between navigation links using a crossfade (made by Blu, from the Discord community)
+- [Clip-Path Transitions](https://svelte.dev/repl/b5ad281ae8024b629b545c70c9e8764d?version=3.29.7) showcases how to use clip paths and custom transitions to create magical in-and-out transitions (made by Faber, from the Discord community)
+
+**Learning Resources**
+- [lihautan](https://www.youtube.com/channel/UCbmC3HP3FaAFdcZkui8YoMQ/featured) has been making easy-to-follow videos to share his in-depth knowledge of Svelte.
+- [Lessons From Building a Static Site Generator](https://nicholasreese.com/lessons-from-building-a-static-site-generator/) shares the backstory and thinking behind Elder.js - and the design decision made along the way.
+- [Svelte Tutorial and Projects Course ](https://www.udemy.com/course/svelte-tutorial-and-projects-course/) is a udemy course by John Smilga where students learn Svelte.js by building interesting projects.
+- [Building Pastebin on IPFS - with FastAPI, Svelte, and IPFS](https://amalshaji.wtf/building-pastebin-on-ipfs-with-fastapi-svelte-and-ipfs) explains how to make a distributed pastebin-like application.
+
+
+**Components, Libraries & Tools**
+- [svelte-crossword](https://russellgoldenberg.github.io/svelte-crossword/) is a customizable crossword puzzle component for Svelte.
+- [svelte-cloudinary](https://github.com/cupcakearmy/svelte-cloudinary) makes it easy to integrate Cloudinary with Svelte (including Typescript and SSR support)
+- [Svelte Nova](https://extensions.panic.com/extensions/sb.lao/sb.lao.svelte-nova/) extends the new Nova editor to support Svelte
+- [saos](https://github.com/shiryel/saos) is a small svelte component to animate your elements on scroll.
+- [Svelte-nStore](https://github.com/lacikawiz/svelte-nStore) is a general purpose store replacement that fulfills the Svelte store contract and adds getter and calculation features.
+- [svelte-slimscroll](https://github.com/MelihAltintas/svelte-slimscroll) is a Svelte Action that transforms any div into a scrollable area with a nice scrollbar.
+- [svelte-typewriter](https://github.com/henriquehbr/svelte-typewriter) is a simple and reusable typewriter effect for your Svelte applications
+- [svelte-store-router](https://github.com/zyxd/svelte-store-router) is a store-based router for Svelte that suggests that routing is just another global state and History API changes are just an optional side-effects of this state.
+- [Routify](https://routify.dev/blog/routify-2-released) just released version 2 of its Svelte router.
+- [svelte-error-boundary](https://www.npmjs.com/package/@crownframework/svelte-error-boundary) provides a simple error boundary component for Svelte that can be can be used with both DOM and SSR targets.
+- [svelte2dts](https://www.npmjs.com/package/svelte2dts) generates d.ts files from svelte files, creating truly sharable and well typed components.
+
+## See you next month!
+
+Got an idea for something to add to the Showcase? Want to get involved more with Svelte? We're always looking for maintainers, contributors and fanatics... Check out the [Svelte Society](https://sveltesociety.dev/), [Reddit](https://www.reddit.com/r/sveltejs/) and [Discord](https://discord.com/invite/yy75DKs) to get involved!
+
+That's all for the year, folks! See you in January 😎
diff --git a/src/compiler/preprocess/index.ts b/src/compiler/preprocess/index.ts
index 1de41cf9bf..b51b67bb23 100644
--- a/src/compiler/preprocess/index.ts
+++ b/src/compiler/preprocess/index.ts
@@ -83,8 +83,81 @@ async function replace_async(
return out.concat(final_content);
}
-/**
- * Convert a preprocessor output and its leading prefix and trailing suffix into StringWithSourceMap
+/**
+ * Import decoded sourcemap from mozilla/source-map/SourceMapGenerator
+ * Forked from source-map/lib/source-map-generator.js
+ * from methods _serializeMappings and toJSON.
+ * We cannot use source-map.d.ts types, because we access hidden properties.
+ */
+function decoded_sourcemap_from_generator(generator: any) {
+ let previous_generated_line = 1;
+ const converted_mappings = [[]];
+ let result_line;
+ let result_segment;
+ let mapping;
+
+ const source_idx = generator._sources.toArray()
+ .reduce((acc, val, idx) => (acc[val] = idx, acc), {});
+
+ const name_idx = generator._names.toArray()
+ .reduce((acc, val, idx) => (acc[val] = idx, acc), {});
+
+ const mappings = generator._mappings.toArray();
+ result_line = converted_mappings[0];
+
+ for (let i = 0, len = mappings.length; i < len; i++) {
+ mapping = mappings[i];
+
+ if (mapping.generatedLine > previous_generated_line) {
+ while (mapping.generatedLine > previous_generated_line) {
+ converted_mappings.push([]);
+ previous_generated_line++;
+ }
+ result_line = converted_mappings[mapping.generatedLine - 1]; // line is one-based
+ } else if (i > 0) {
+ const previous_mapping = mappings[i - 1];
+ if (
+ // sorted by selectivity
+ mapping.generatedColumn === previous_mapping.generatedColumn &&
+ mapping.originalColumn === previous_mapping.originalColumn &&
+ mapping.name === previous_mapping.name &&
+ mapping.generatedLine === previous_mapping.generatedLine &&
+ mapping.originalLine === previous_mapping.originalLine &&
+ mapping.source === previous_mapping.source
+ ) {
+ continue;
+ }
+ }
+ result_line.push([mapping.generatedColumn]);
+ result_segment = result_line[result_line.length - 1];
+
+ if (mapping.source != null) {
+ result_segment.push(...[
+ source_idx[mapping.source],
+ mapping.originalLine - 1, // line is one-based
+ mapping.originalColumn
+ ]);
+ if (mapping.name != null) {
+ result_segment.push(name_idx[mapping.name]);
+ }
+ }
+ }
+
+ const map = {
+ version: generator._version,
+ sources: generator._sources.toArray(),
+ names: generator._names.toArray(),
+ mappings: converted_mappings
+ };
+ if (generator._file != null) {
+ (map as any).file = generator._file;
+ }
+ // not needed: map.sourcesContent and map.sourceRoot
+ return map;
+}
+
+/**
+ * Convert a preprocessor output and its leading prefix and trailing suffix into StringWithSourceMap
*/
function get_replacement(
filename: string,
@@ -109,6 +182,10 @@ function get_replacement(
if (typeof(decoded_map.mappings) === 'string') {
decoded_map.mappings = decode_mappings(decoded_map.mappings);
}
+ if ((decoded_map as any)._mappings && decoded_map.constructor.name === 'SourceMapGenerator') {
+ // import decoded sourcemap from mozilla/source-map/SourceMapGenerator
+ decoded_map = decoded_sourcemap_from_generator(decoded_map);
+ }
sourcemap_add_offset(decoded_map, get_location(offset + prefix.length));
}
const processed_with_map = StringWithSourcemap.from_processed(processed.code, decoded_map);
@@ -164,7 +241,7 @@ export default async function preprocess(
async function preprocess_tag_content(tag_name: 'style' | 'script', preprocessor: Preprocessor) {
const get_location = getLocator(source);
- const tag_regex = tag_name == 'style'
+ const tag_regex = tag_name === 'style'
? /|
diff --git a/test/sourcemaps/samples/source-map-generator/test.js b/test/sourcemaps/samples/source-map-generator/test.js
new file mode 100644
index 0000000000..72ad1da1d8
--- /dev/null
+++ b/test/sourcemaps/samples/source-map-generator/test.js
@@ -0,0 +1 @@
+export { test } from '../preprocessed-styles/test';