diff options
Diffstat (limited to 'examples/snowpack/src/pages/tutorials')
-rw-r--r-- | examples/snowpack/src/pages/tutorials/getting-started.md | 237 | ||||
-rw-r--r-- | examples/snowpack/src/pages/tutorials/quick-start.md | 61 | ||||
-rw-r--r-- | examples/snowpack/src/pages/tutorials/react.md | 343 | ||||
-rw-r--r-- | examples/snowpack/src/pages/tutorials/svelte.md | 330 |
4 files changed, 971 insertions, 0 deletions
diff --git a/examples/snowpack/src/pages/tutorials/getting-started.md b/examples/snowpack/src/pages/tutorials/getting-started.md new file mode 100644 index 000000000..07687dffa --- /dev/null +++ b/examples/snowpack/src/pages/tutorials/getting-started.md @@ -0,0 +1,237 @@ +--- +layout: ../../layouts/content.astro +title: 'Starting a New Project' +description: This guide shows you how to set up Snowpack from scratch in a Node.js project. Along the way learn key concepts of Snowpack and unbundled development. +--- + +Welcome to Snowpack! This guide shows you how to set up Snowpack from scratch in a Node.js project. Along the way learn key concepts of Snowpack and unbundled development + +In this guide you'll learn + +- What makes Snowpack so fast? (hint: unbundled development!) +- What are JavaScript ES Modules (ESM)? +- Creating your first project +- Starting Snowpack's development server +- Building your first project +- Customizing Snowpack with plugins + +> 💡 Tip: This guide walks you through creating the [Snowpack minimal app template](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/) from scratch. Spin up a copy of the final [using the create-snowpack-app command line tool](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/). + +Prerequisites: Snowpack is a command line tool installed from npm. This guide assumes a basic understanding of JavaScript, npm, and how to run commands in the terminal. + +Snowpack also requires a modern browser during development. Any semi-recent release of Firefox, Chrome, Safari, or Edge for example. + +## Install Snowpack + +To get started, create an empty directory for your new Snowpack project. Create the new directory using your favorite GUI or by running the command line as shown here: + +```bash +mkdir my-first-snowpack +cd my-first-snowpack +``` + +Snowpack is a package installed from npm. Create a `package.json` file in your project directory to manage your dependencies. Run this command in your project to create a simple, empty `package.json`: + +```bash +npm init +``` + +> 💡 Tip: In a hurry? Run `npm init --yes` to skip the prompts and generate a package.json with npm's default, recommended fields. + +Now install Snowpack to your `dev dependencies` with this command: + +``` +npm install --save-dev snowpack +``` + +> 💡 Tip: Snowpack can install globally via `npm install -g snowpack`. But, we recommend installing locally in every project via `--save-dev`/`--dev`. Run the Snowpack command-line tool locally via package.json "scripts", npm's `npx snowpack`, or via `yarn snowpack`. + +## Snowpack's development server + +Adding a basic HTML file allows us to run Snowpack's development server, an instant development environment for unbundled development. The development server builds a file only when it's requested by the browser. That means that Snowpack can start up instantly (usually in **\<50 ms**) and scale to infinitely large projects without slowing down. In contrast, it's common to see 30+ second development startup times when building large apps with a traditional bundler. + +Create an `index.html` in your project with the following contents: + +```html +<!DOCTYPE html> +<html lang="en"> + <head> + <meta charset="utf-8" /> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <meta name="description" content="Starter Snowpack App" /> + <title>Starter Snowpack App</title> + </head> + <body> + <h1>Welcome to Snowpack!</h1> + </body> +</html> +``` + +Add the Snowpack development server to `package.json` under as the `start` script: + +```diff + "scripts": { ++ "start": "snowpack dev", + "test": "echo \"Error: no test specified\" && exit 1" + }, + +``` + +Run the following on the command line to start the Snowpack development server + +``` +npm run start +``` + +If all went well, Snowpack automatically opens your site in a new browser! + +<div class="frame"><img src="/img/guides/getting-started/run-snowpack.jpg" alt="Side by side of the terminal showing the dev server output. The dev server output displays the localhost address the project is running on. In a browser window you can see the running project on localhost, which is 'Welcome to Snowpack' on a white background." class="screenshot"/></div> + +Congratulations! You now have a Snowpack project up and running! Try changing the index.html and saving while the server is running, the site should refresh and show changes automatically. + +## Using JavaScript + +Learn more about how Snowpack processes JavaScript by adding a simple "hello world" script. JavaScript's native ES Module (ESM) syntax is the magic behind Snowpack's unbundled development. There's a good chance that you're already familiar with ESM, and you just don't know it! ESM lets you define explicit imports & exports that browsers and build tools can better understand and optimize for. If you're familiar with the `import` and `export` keywords in JavaScript, then you already know ESM! + +Create a new JavaScript file called `hello-world.js` that exports a single `helloWorld` function: + +```js +// my-first-snowpack/hello-world.js +export function helloWorld() { + console.log('Hello World!'); +} +``` + +Then create an `index.js` that imports your new module using ESM syntax: + +```js +// my-first-snowpack/index.js +import { helloWorld } from './hello-world.js'; + +helloWorld(); +``` + +Snowpack scans for files referenced in `index.html`, so add your `index.js` to `index.html` at the bottom of the `<body>` tag: + +```diff + <body> + <h1>Welcome to Snowpack!</h1> ++ <script type="module" src="/index.js"></script> + </body> +``` + +Check your console on your Snowpack site. You should see "Hello World!" Try making a change to the module. Snowpack rebuilds that module without rebuilding the rest of your code. Snowpack builds **every file individually and caches it indefinitely.** Your development environment never builds a file more than once and your browser never downloads a file twice (until it changes). This is the real power of unbundled development, and the secret behind what makes Snowpack so fast. + +<div class="frame"><img src="/img/guides/getting-started/hello-world.gif" alt="Gif showing the code next to the project running in the browser. On save the console shows 'Hello World!'. On edit and save of the `hello-world.js` file to be 'Hello everyone!' instead, that instantly shows in the browser console." class="screenshot"/></div> + +## Using npm Packages + +Snowpack builds any npm package into ESM web modules. npm packages are mainly published using a module syntax (Common.js, or CJS) that can't run on the web without some build processing. Even if you write your application using browser-native ESM `import` and `export` statements that would all run directly in the browser, trying to import any one npm package forces you back into bundled development. + +**Snowpack takes a different approach:** instead of bundling your entire application for this one requirement, Snowpack processes your dependencies separately. Here's how it works: + +``` +node_modules/react/**/* -> http://localhost:3000/web_modules/react.js +node_modules/react-dom/**/* -> http://localhost:3000/web_modules/react-dom.js +``` + +1. Snowpack scans your website/application for all used npm packages. +2. Snowpack reads these installed dependencies from your `node_modules` directory. +3. Snowpack bundles all your dependencies separately into single JavaScript files. For example: `react` and `react-dom` convert to `react.js` and `react-dom.js`, respectively. +4. Each resulting file runs directly in the browser, and imported via ESM `import` statements. +5. Because your dependencies rarely change, Snowpack rarely needs to rebuild them. + +After Snowpack builds your dependencies, import any package and run it directly in the browser with zero extra bundling or tooling. This ability to import npm packages natively in the browser (without a bundler) is the foundation that all unbundled development and the rest of Snowpack builds on top of. + +Snowpack lets you import npm packages directly in the browser. Even if a package is using a legacy format, Snowpack up-converts the package to ESM before serving it to the browser. + +> 💡 Tip: when you start up your development server or run a new build, you may see a message that Snowpack is "installing dependencies." This means that Snowpack is converting your dependencies to run in the browser. + +Install the canvas-confetti package from npm and use it with the following command: + +```bash +npm install --save canvas-confetti +``` + +Now head to `index.js` and add this code: + +```diff +helloWorld(); + ++import confetti from 'canvas-confetti'; ++confetti.create(document.getElementById('canvas'), { ++ resize: true, ++ useWorker: true, ++ })({ particleCount: 200, spread: 200 }); +``` + +> 💡 Tip: did you know, with Snowpack you can also add this code directly to your HTML if you prefer! + +You should now see a nifty confetti effect on your site. + +<div class="frame"><img src="/img/guides/getting-started/npm-snowpack-confetti.gif" alt="Gif showing the code next to the project running in the browser. When the code snippet is added and saved, a confetti effect shows in the browser" class="screenshot"/></div> + +> 💡 Tip: not all npm modules may work well in the browser. Modules dependent on Node.js built-in modules need a polyfill. You can enable this polyfill by setting Snowpack’s [`packageOptions.polyfillNode` configuration option](/reference/configuration#packageoptions.polyfillnode) to `true`. + +## Adding CSS + +Snowpack natively supports many file types. CSS and CSS Modules for example. Add a simple CSS file to see how it works. + +Add the following css as a new `index.css` file: + +```css +body { + font-family: sans-serif; +} +``` + +Include it in your project by adding it to index.html in the `<head>` + +```diff + <meta name="description" content="Starter Snowpack App" /> ++ <link rel="stylesheet" type="text/css" href="/index.css" /> + <title>Starter Snowpack App</title> +``` + +<div class="frame"><img src="/img/guides/getting-started/snowpack-font-css.jpg" alt="image showing the effects of the new CSS file: the font has changed from serif to sans-serif" class="screenshot"/></div> + +## Build for production/deployment + +OK you've now built a very simple website and you want to launch it. It's time to use `snowpack build`. + +By default, `snowpack build` builds your site using the same unbundled approach as the `dev` command. Building is integrated with your development setup which guarantees a near-exact copy of the same code that you saw during development. + +Add the `snowpack build` command to package.json so it's easier to run on the command line: + +```diff + "scripts": { + "start": "snowpack dev", ++ "build": "snowpack build", + "test": "echo \"Error: no test specified\" && exit 1" + + }, + +``` + +Now you can run this in your terminal: + +```bash +npm run build +``` + +You should see a new directory called `build` that contains a copy of your Snowpack project ready for deployment. + +<div class="frame"><img src="/img/guides/getting-started/snowpack-build.gif" alt="GIF terminal running Snowpack build, showing output, then clicking on the new `build` directory" class="screenshot"/></div> + +## Next Steps + +You've just learned the major concepts of unbundled developments and built a tiny Snowpack project. But that's just the beginning with Snowpack. + +What's next? Our docs site has several great resources + +- [Bundling for production guide](/guides/optimize-and-bundle): how to connect a bundler like Webpack to optimize code for production deployments +- [Plugins](/plugins): a list of plugins that allow you to integrate your favorite tools with Snowpack +- [Templates/Examples](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/cli): pre-built projects you can build on or just explore using many popular frameworks and tools +- [Guides](/guides): Step by step deep dives on building with and for Snowpack. Includes frameworks like React and Svelte. + +If you have any questions, comments, or corrections, we'd love to hear from you in the Snowpack [discussion](https://github.com/snowpackjs/snowpack/discussions) forum or our [Snowpack Discord community](https://discord.gg/rS8SnRk). diff --git a/examples/snowpack/src/pages/tutorials/quick-start.md b/examples/snowpack/src/pages/tutorials/quick-start.md new file mode 100644 index 000000000..a3960453f --- /dev/null +++ b/examples/snowpack/src/pages/tutorials/quick-start.md @@ -0,0 +1,61 @@ +--- +layout: ../../layouts/content.astro +title: Quick Start +description: A very basic guide for developers who want to run Snowpack as quickly as possible. +--- + +### Install Snowpack + +```bash +# npm: +npm install --save-dev snowpack +# yarn: +yarn add --dev snowpack +# pnpm: +pnpm add --save-dev snowpack +``` + +### Run the Snowpack CLI + +```bash +npx snowpack [command] +yarn run snowpack [command] +pnpm run snowpack [command] +``` + +Throughout our documentation, we'll use `snowpack [command]` to document the CLI. To run your locally installed version of Snowpack, add the `npx`/`yarn run`/`pnpm run` prefix of the package manager that you used to install Snowpack. + +For long-term development, the best way to use Snowpack is with a package.json script. This reduces your own need to remember exact Snowpack commands/configuration, and lets you share some common scripts with the rest of your team (if applicable). + +```js +// Recommended: package.json scripts +// npm run start (or: "yarn run ...", "pnpm run ...") +"scripts": { + "start": "snowpack dev", + "build": "snowpack build" +} +``` + +### Serve your project locally + +``` +snowpack dev +``` + +This starts the local dev server for development. By default this serves your current working directory to the browser, and will look for an `index.html` file to start. You can customize which directories you want to serve via the ["mount"](/reference/configuration) configuration. + +### Build your project + +``` +snowpack build +``` + +This builds your project into a static `build/` directory that you can deploy anywhere. You can customize your build via [configuration](/reference/configuration). + +### See all commands & options + +``` +snowpack --help +``` + +The `--help` flag will display helpful output. diff --git a/examples/snowpack/src/pages/tutorials/react.md b/examples/snowpack/src/pages/tutorials/react.md new file mode 100644 index 000000000..7364f03cc --- /dev/null +++ b/examples/snowpack/src/pages/tutorials/react.md @@ -0,0 +1,343 @@ +--- +layout: ../../layouts/content-with-cover.astro +title: 'Getting Started with React' +description: 'Get started with this in-depth tutorial on how to build React applications and websites with Snowpack and developer tools like React Fast Refresh' +date: 2020-12-01 +tags: communityGuide +cover: '/img/ReactGuide.jpg' +img: '/img/ReactGuide.jpg' +--- + +Snowpack is a great fit for [React](https://reactjs.org/) projects of any size. It's easy to get started and can scale to projects containing thousands of components and pages without any impact on development speed. Unlike traditional React application tooling, Snowpack saves you from getting bogged down with complex bundler setups and configuration files. + +In this guide, you'll go from an empty directory to a fully configured Snowpack project with support for React and several other useful developer tools. In the process, you'll learn: + +- How to set up your Snowpack development environment +- Adding your first React component +- Working with CSS, images and other web assets +- Enabling [Fast Refresh](https://reactnative.dev/docs/fast-refresh) mode for React +- Connecting your favorite tools + +Prerequisites: Snowpack is a command line tool installed from npm. This guide assumes a basic understanding of Node.js, npm, and how to run commands in the terminal. Knowledge of React is not required, Snowpack is a great way to learn React! + +> 💡 Tip: if you want to jump to the end to see a full featured React setup, the [Create Snowpack App React template](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/app-template-react) comes with everything you'll learn in this guide plus other useful tools. + +## Getting started + +The easiest way to start a new Snowpack project is with [Create Snowpack App](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/cli), a tool to set up Snowpack in a new directory. `@snowpack/project-template-minimal` is a Create Snowpack App template for a simple, bare-bones Snowpack project setup that the rest of this guide builds on. + +To get started, open your terminal and head to a directory where you want to put your new project. Now run the following command in your terminal to create a new directory called `react-snowpack` with the minimal template automatically installed. + +```bash +npx create-snowpack-app react-snowpack --template @snowpack/app-template-minimal +``` + +You can now head to the new directory and start Snowpack with the following two commands: + +```bash +cd react-snowpack +npm run start +``` + +You should see your new website up and running! + +> 💡 Tip: the `README.md` in your new project contains useful information about what each file does. + +<div class="frame"><img src="/img/guides/react/minimalist-hello-world.png" alt="screenshot of project-template-minimal, which shows 'Hello world' in text on a white background." class="screenshot"/></div> + +Now that you have a basic project up and running, to install React, run the following command in your project directory: + +```bash +npm install react react-dom --save +``` + +> 💡 Tip: add the `--use-yarn` or `--use-pnpm` flag to use something other than npm + +## Create your first React component + +React relies on a special templating language called JSX. If you're familiar with React then you already know JSX: it's React's templating language that allows you to write something like `<App />` or `<Header></Header>` directly in your JavaScript code. + +Snowpack has built in support for JSX in files using the `.jsx` extension. That means that there's no plugins or configuration needed to write your first React component. Rename `index.js` file to `index.jsx` so that Snowpack knows to handle JSX in the file: + +```bash +mv index.js index.jsx +``` + +> 💡 Tip: you do not need to update your `index.html` script tag reference to point to `index.jsx`. Browsers don't speak JSX (or TypeScript, for that matter), so any compile-to-JS file formats compile to `.js` in the final browser build. This is good to keep in mind when you're referencing built files in HTML `<script src="">` and `<link href="">` elements. + +You can now import React in `index.jsx` and add a simple test component just to make sure it's working: + +```diff + /* Add JavaScript code here! */ +- console.log('Hello World! You did it! Welcome to Snowpack :D'); ++ import React from 'react'; ++ import ReactDOM from 'react-dom'; ++ ReactDOM.render(<div>"HELLO REACT"</div>, document.getElementById('root')); +``` + +Since the React code is rendering into an element with the ID `root`, you'll need to add that to `index.html`: + +```diff + <body> +- <h1>Welcome to Snowpack!</h1> ++ <div id="root"></div> + <script type="module" src="/index.js"></script> + </body> +``` + +<div class="frame"><img src="/img/guides/react/minimalist-hello-world-react.png" alt="screenshot of the project, which shows 'HELLO REACT' on a white background" class="screenshot"/></div> + +You've just created your first React component in Snowpack! + +## Customize your project layout + +Since you'll be adding a bunch of new files, you probably don't want them crowding up your top-level root directly. Snowpack is flexible enough to support whatever project layout that you prefer. In this guide, you'll learn how to use a popular project pattern from the React community. + +``` +📁 src : your React components and their assets (CSS, images) + ↳ index.jsx +📁 public : global assets like images, fonts, icons, and global CSS + ↳ index.css + ↳ index.html +``` + +Use your favorite visual editor to rearrange and rename, or run these commands in the terminal: + +```bash +mkdir src +mkdir public +mv index.jsx src/index.jsx +mv index.html public/index.html +mv index.css public/index.css +``` + +This means if you are running Snowpack right now, the site is now broken as the files are all in different places. Lets add a "mount" configuration to update your site to your new project layout. + +The `mount` configuration changes where Snowpack looks for and builds files. Every Snowpack project comes with a `snowpack.config.js` file for any configuration that you might need. Right now, you should see a configuration file with empty options. Add this to the empty `mount` object: + +```diff + mount: { +- /* ... */ ++ // directory name: 'build directory' ++ public: '/', ++ src: '/dist', + }, +``` + +<img src="/img/guides/react/folderstructure.png" alt="The original file configuration had Snowpack building the directory structure the same as the directories in the project, including root. Now the config builds only src and public. Src to the dist folder and public to root." /> + +`mount` is part of the [Snowpack Configuration API](/reference/configuration). It allows you to customize the file structure of your project. The key is the name of the directory and the value is where you'd like them in the final build. With this new configuration, Snowpack builds files in `public` like `public/index.css` directory into `index.css`. It builds files in `src` like `src/index.js` into `/dist/index.js`, so you'll need to change that path in your `index.html`: + +```diff + <body> + <h1>Welcome to Snowpack!</h1> + <div id="root"></div> +- <script type="module" src="/index.js"></script> ++ <script type="module" src="/dist/index.js"></script> + </body> +``` + +You'll need to restart Snowpack for configuration file changes. When you start up again, if it worked, it should look the same. + +Create a new file at `src/App.jsx` and paste the following code into this new file to create an `App` component: + +```jsx +import React, { useState, useEffect } from 'react'; + +function App() { + // Create the count state. + const [count, setCount] = useState(0); + // Update the count (+1 every second). + useEffect(() => { + const timer = setTimeout(() => setCount(count + 1), 1000); + return () => clearTimeout(timer); + }, [count, setCount]); + // Return the App component. + return ( + <div className="App"> + <header className="App-header"> + <p> + Page has been open for <code>{count}</code> seconds. + </p> + </header> + </div> + ); +} + +export default App; +``` + +Now include it in `index.jsx` + +```diff + import React from 'react'; + import ReactDOM from 'react-dom'; +- ReactDOM.render(<div>"HELLO WORLD"</div>, document.getElementById('root')); ++ import App from './App.jsx'; ++ ReactDOM.render( ++ <React.StrictMode> ++ <App /> ++ </React.StrictMode>, ++ document.getElementById('root'), ++ ); +``` + +> 💡 Tip: [Strict Mode](https://reactjs.org/docs/strict-mode.html) is a tool for highlighting potential problems in React code. + +You shouldn't need to restart Snowpack to see this, it should look like this: + +<div class="frame"><img src="/img/guides/react/minimalist-hello-world-react-timer.png" alt="screenshot of the project with text that says 'Page has been open for' and the number of seconds then 'seconds'" class="screenshot"/></div> + +## Styling your project + +When you add assets like images or CSS, Snowpack includes them in your final build. If you already know React, this process should look pretty familiar. + +> 💡 Tip: as you're doing this, you should not need to reload the page or restart Snowpack. Snowpack automatically updates the project in the browser as you edit code. + +Add this file [`logo.svg`](https://github.com/snowpackjs/snowpack/blob/main/create-snowpack-app/app-template-react/src/logo.svg) to your `src` directory. Now you can import it into your `App.jsx` and use it in an `img` tag to display it. + +```diff + import React, { useState, useEffect } from 'react'; ++ import logo from './logo.svg'; + + function App() { + // Create the count state. + const [count, setCount] = useState(0); + // Create the counter (+1 every second). + useEffect(() => { + const timer = setTimeout(() => setCount(count + 1), 1000); + return () => clearTimeout(timer); + }, [count, setCount]); + // Return the App component. + return ( + <div className="App"> + <header className="App-header"> ++ <img src={logo} className="App-logo" alt="logo" /> + <p> +``` + +<div class="frame"><img src="/img/guides/react/minimalist-hello-world-react-logo.png" alt="the React logo (a blue atom) is now at the top of the page" class="screenshot"/></div> + +The project already has index.css for global styles. For CSS that's only for a specific component, a common design pattern is to add it in a CSS file with the same base name as the component. The style file for `App.jsx` would be `App.css` with this pattern. + +> 💡 Tip: Snowpack has built-in support for [CSS Modules](/reference/supported-files) and if you'd like to use Sass there is an official [Sass Plugin](/guides/sass/). + +Create `src/App.css` and add this CSS: + +```css +.App { + text-align: center; +} + +.App p { + margin: 0.4rem; +} + +.App-logo { + height: 40vmin; +} + +@media (prefers-reduced-motion: no-preference) { + .App-logo { + animation: App-logo-spin infinite 20s linear; + } +} + +.App-header { + background-color: #282c34; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + color: white; +} + +@keyframes App-logo-spin { + from { + transform: rotate(0deg); + } + to { + transform: rotate(360deg); + } +} +``` + +To use this CSS, head to `App.jsx` and import it + +```diff + import logo from './logo.svg'; ++ import './App.css'; +``` + +<div class="frame"><img src="/img/guides/react/react.gif" alt="The page now has centered items, a grey background, styled fonts, and the React logo has an animation that rotates it." class="screenshot"/></div> + +## Making Snowpack Even Faster with Fast Refresh + +[React Fast Refresh](https://reactnative.dev/docs/fast-refresh)? What's that? It's a Snowpack enhancement that lets you push individual file changes to update the browser without refreshing the page or clearing component state. + +React projects are often interactive and include state. For example, this project you're building has a state that is the amount of time on the page. When developing with state it's useful not to lose it while you edit code. React Fast Refresh shows you updates without refreshing the entire page. Showing you how to add this is also a good intro to Snowpack plugins. Snowpack starts with a minimal setup with the perspective that you can add what you need through the plugin system. + +Start by enabling [Hot Module Replacement](/concepts/hot-module-replacement) in your project. HMR is the system that lets Snowpack push updates to the browser without a full page refresh, a requirement for Fast Refresh. You can enable HMR for React by adding a small snippet of code to your `src/index.jsx` file. + +```diff + ReactDOM.render( + <React.StrictMode> + <App /> + </React.StrictMode>, + document.getElementById('root'), + ); ++ // Hot Module Replacement (HMR) - Remove this snippet to remove HMR. ++ // Learn more: https://www.snowpack.dev/concepts/hot-module-replacement ++ if (import.meta.hot) { ++ import.meta.hot.accept(); ++ } +``` + +Now when you change `App.jsx` the page updates to show your changes without a full refresh. + +<div class="frame"><img src="/img/guides/react/hmr.gif" alt="GIF showing code side by side with the app. A change in made to App.jsx and it shows immediately when the file is changed. The counter keeps counting uninterrupted." class="screenshot"/></div> + +HMR can save you time on its own, but you may notice in the example above that the counter on the page still resets to 0. This can slow down your development, especially when you're trying to debug a specific component state problem. Lets enable Fast Refresh to preserve component state across updates. + +To enable Fast Refresh, you'll need to install the `@snowpack/plugin-react-refresh` package. This package is a Snowpack plugin, which you can use to enhance or customize Snowpack with all sorts of new behaviors. To start, install the package in your project: + +```bash +npm install @snowpack/plugin-react-refresh --save-dev +``` + +Once installed, you'll need to add the plugin to your Snowpack configuration file so that Snowpack knows to use it: + +```diff + module.exports = { + mount: { + public: '/', + src: '/dist', + }, +- plugins: [] ++ plugins: ['@snowpack/plugin-react-refresh'], + }; +``` + +Restart Snowpack to apply the new plugin, and then try changing the `App.jsx` component again. If Fast Refresh is working properly, the counter keeps its value across changes, without resetting to zero. + +<div class="frame"><img src="/img/guides/react/react-fast-refresh.gif" alt="GIF showing code side by side with the app. A change in made to App.jsx and it shows immediately when the file is changed. The counter keeps counting uninterrupted." class="screenshot"/></div> + +## Going further + +Great job! You're now ready to build the React project of your dreams with Snowpack. Want to tweet your accomplishment to the world? Click the button below: + +<a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-text="I just learned how to build a React app with #Snowpack. Check out the tutorial:" data-show-count="false">Tweet</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> + +At this point you have the basics and have a great starter for any React project. But if you compare with the official [Snowpack React template](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/app-template-react) you'll notice it has some other developer tools you might find useful: + +- [Prettier](https://prettier.io/)—a popular code formatter + +- [Tests](/guides/testing)—Snowpack supports any popular JavaScript testing framework + +- [`@snowpack/plugin-dotenv`](https://github.com/snowpackjs/snowpack/tree/main/plugins/plugin-dotenv)—Use `dotenv` in your Snowpack. This is useful for environment specific variables + +If you'd like to use Typescript with Snowpack and React, check out the [Snowpack React Typescript](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/app-template-react-typescript) starter. + +If you have any questions, comments, or corrections, we'd love to hear from you in the Snowpack [discussion](https://github.com/snowpackjs/snowpack/discussions) forum or our [Snowpack Discord community](https://discord.gg/rS8SnRk). diff --git a/examples/snowpack/src/pages/tutorials/svelte.md b/examples/snowpack/src/pages/tutorials/svelte.md new file mode 100644 index 000000000..c25f2bcdb --- /dev/null +++ b/examples/snowpack/src/pages/tutorials/svelte.md @@ -0,0 +1,330 @@ +--- +layout: ../../layouts/content-with-cover.astro +title: 'Getting Started with Svelte' +description: 'Get started with this in-depth tutorial on how to build Svelte applications and websites with Snowpack' +date: 2020-12-01 +sidebarTitle: Svelte +tags: communityGuide +cover: '/img/SvelteGuide.jpg' +img: '/img/SvelteGuide.jpg' +--- + +Snowpack is a great fit for [Svelte](https://svelte.dev/) projects of any size. It's easy to get started and can scale to projects containing thousands of components and pages without any impact on development speed. Unlike traditional Svelte application tooling, Snowpack saves you from getting bogged down with complex bundler setups and configuration files. + +> Snowpack is … astonishingly fast, and has a beautiful development experience (hot module reloading, error overlays and so on), and we've been working closely with the Snowpack team on features like SSR[Server-side rendering]. The hot module reloading is particularly revelatory. - [Rich Harris, creator of Svelte](https://svelte.dev/blog/whats-the-deal-with-sveltekit) + +This guide is a step by step from an empty directory to a fully configured Snowpack project, in the process teaching: + +- How to set up your Snowpack development environment +- Adding your first Svelte component +- Importing images and other web assets +- Enabling Hot Module Replacement (HMR) +- Connecting your favorite tools + +Prerequisites: Snowpack is a command-line tool installed from npm. This guide assumes a basic understanding of Node.js, npm, and how to run commands in the terminal. Knowledge of Svelte is not required: Snowpack is an excellent way to learn Svelte! + +> 💡 Tip: a [Svelte/Snowpack](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/app-template-svelte) working example is available in our Create Snowpack App templates. + +## Getting started + +The easiest way to start a new Snowpack project is with [Create Snowpack App](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/cli), a tool for creating a new project based on our example templates. `@snowpack/app-template-minimal` is a Create Snowpack App template for a simple, bare-bones Snowpack project setup that the rest of this guide builds on. + +Run the following command in your terminal to create a new directory called `svelte-snowpack` with the minimal template installed: + +```bash +npx create-snowpack-app svelte-snowpack --template @snowpack/app-template-minimal +``` + +Head to the new `svelte-snowpack` directory and start Snowpack with the following two commands: + +```bash +cd svelte-snowpack +npm run start +``` + +You should see your new website up and running! + +<div class="frame"><img src="/img/guides/react/minimalist-hello-world.png" alt="screenshot of project-template-minimal, which shows 'Hello world' in text on a white background." class="screenshot"/></div> + +Now that you have a basic project up and running! The next step is to install Svelte. Run the following command in your project directory: + +```bash +npm install svelte --save +``` + +> 💡 Tip: add the `--use-yarn` or `--use-pnpm` flag to use something other than npm + +```bash +npm install @snowpack/plugin-svelte --save-dev +``` + +Snowpack [plugins](/plugins) are a way to extend Snowpack's capabilities without having to do custom configuration yourself. Install the `@snowpack/plugin-svelte` plugin so that Snowpack knows how built `.svelte` files into JavaScript and CSS files that run in the browser: + +Once installed, you'll need to add the plugin to your Snowpack configuration file (`snowpack.config.js`) so that Snowpack knows to use it: + +```diff +// snowpack.config.js + +module.exports = { + mount: { + /* ... */ + }, + plugins: [ +- /* ... */ ++ '@snowpack/plugin-svelte' + ], +``` + +Restart your Snowpack dev server to run it with the new configuration. Exit the process (ctrl + c in most Windows/Linux/macOS) and start it again with `npm run start`. + +> 💡 Tip: Restart the Snowpack development server when you make configuration changes (changes to the `snowpack.config.js`). + +Snowpack will recognize the new dependency (Svelte, or "svelte/internal") and print the following output as installs your dependencies for the frontend: + +```bash +[snowpack] installing dependencies... +[snowpack] ✔ install complete! [0.45s] +[snowpack] + ⦿ web_modules/ size gzip brotli + ├─ svelte-hmr/runtime/hot-api-esm.js 22.17 KB 7.42 KB 6.3 KB + ├─ svelte-hmr/runtime/proxy-adapter-dom.js 5.17 KB 1.65 KB 1.38 KB + └─ svelte/internal.js 52.78 KB 13.24 KB 11.45 KB +``` + +## Create your first Svelte component + +You now have your Snowpack environment set up to build `.svelte` files for the browser. Now it's time to create your first Svelte component file! + +Create a file named `App.svelte` in your project directory with the following code: + +```html +<!-- App.svelte --> +<script> + /* component logic will go here */ +</script> +<style> + /* css will go here */ +</style> +<div class="App"> + <header class="App-header"> + <a + class="App-link" + href="https://svelte.dev" + target="_blank" + rel="noopener noreferrer" + > + Learn Svelte + </a> + </header> +</div> +``` + +Now you can use the new `App.svelte` file in your `index.js`: + +```diff +// index.js + +/* Add JavaScript code here! */ +-console.log('Hello World! You did it! Welcome to Snowpack :D'); ++import App from "./App.svelte"; + ++let app = new App({ ++ target: document.body, ++}); + ++export default app; +``` + +The page should now say "Learn Svelte". Congratulations! you now have your first Svelte component! + +<div class="frame"><img src="/img/guides/svelte/svelte-component-snowpack.gif" alt="code and site side by side, site is a 'Learn Svelte' link on a white background. When the text is edit to add 'Hello world' and the file saves, the changes show up in the site immediately." class="screenshot"/></div> + +## Customize your project layout + +Snowpack is flexible enough to support whatever project layout that you prefer. In this guide, you'll learn how to use a popular project pattern from the Svelte community. + +``` +📁 src : your Svelte components and their assets (CSS, images) + ↳ index.js + ↳ App.svelte +📁 public : global assets like images, fonts, icons, and global CSS + ↳ index.css + ↳ index.html +``` + +Use your favorite visual editor to rearrange and rename, or run these commands in the terminal: + +```bash +mkdir src +mkdir public +mv index.js src/index.js +mv App.svelte src/App.svelte +mv index.html public/index.html +mv index.css public/index.css +``` + +This means if you are running Snowpack right now, the site is now broken as the files are all in different places. Lets add a "mount" configuration to update your site to your new project layout. + +The `mount` configuration changes where Snowpack scan for and builds files. Head back to the `snowpack.config.js` file you edited when you added `@snowpack/plugin-svelte`. Add this to the empty `mount` object: + +```diff +// snowpack.config.js + + mount: { +- /* ... */ ++ // directory name: 'build directory' ++ public: '/', ++ src: '/dist', + }, +``` + +<img src="/img/guides/folder-structure.png" alt="Graphic shows the original and new folder structures side by side. Arrows indicate that the files are built to where the arrow points. The Original side shows a folder labeled ./ entire directory with an arrow pointing to a folder labeled mysite.com/*. The New side shows a folder labeled ./src/* with an arrow pointing to a folder labeled mysite.com/_dist/*. Then a second folder labeled ./public/* with an arrow pointing to a folder labeled mysite.com/* " /> + +`mount` is part of the [Snowpack Configuration API](/reference/configuration). It allows you to customize the file structure of your project. The key is the name of the directory and the value is where you'd like them in the final build. With this new configuration, Snowpack builds files in the `public` directory - like `public/index.css` - into `index.css`. Likewise, it builds files in `src` like `src/index.js` into `/dist/index.js`, so change that path in your `index.html`: + +```diff +<!-- public/index.html --> + + <body> + <h1>Welcome to Snowpack!</h1> +- <script type="module" src="/index.js"></script> ++ <script type="module" src="/dist/index.js"></script> + </body> +``` + +You'll need to restart Snowpack (stop the process in terminal and then run `npm start` again) for configuration file changes. It should look exactly as it did before, but now using your brand new project folder layout + +## Adding an animated Svelte Logo + +In Svelte you can add CSS directly to your component. This step demonstrates this capability by adding an animated logo. + +[Download `logo.svg`](https://github.com/snowpackjs/snowpack/blob/main/create-snowpack-app/app-template-svelte/public/logo.svg) to your `public` directory. Now you can add it to your `App.svelte` + +```diff +<!-- src/App.svelte --> + + <header class="App-header"> ++ <img src="/logo.svg" class="App-logo" alt="logo" /> + <a + class="App-link" + href="https://svelte.dev" + target="_blank" + rel="noopener noreferrer"> + Learn Svelte + </a> +``` + +<div class="frame"><img src="/img/guides/svelte/svelte-logo-snowpack.jpg" alt="Side by side of code and site. The site now has a very large Svelte logo. The code shows the src/App.svelte file " class="screenshot"/></div> + +With Svelte, CSS can go directly in your `.svelte` component. Add this code to the top of `App.svelte` between the `<style>` tags: + +```html +<!-- src/App.svelte --> + +<style> + .App-header { + background-color: #f9f6f6; + color: #333; + min-height: 100vh; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + font-size: calc(10px + 2vmin); + } + .App-logo { + height: 36vmin; + pointer-events: none; + margin-bottom: 3rem; + animation: App-logo-pulse infinite 1.6s ease-in-out alternate; + } + @keyframes App-logo-pulse { + from { + transform: scale(1); + } + to { + transform: scale(1.06); + } + } +</style> +``` + +<div class="frame"><img src="/img/guides/svelte/svelte-logo-style-snowpack.gif" alt="code and site side by side, when the css is added to the Svelte component, the background becomes a beige, the logo shrinks down, and the logo has a pulsing animation" class="screenshot"/></div> + +## Adding a counter to your Svelte component + +Snowpack is one of the only Svelte dev environments to support Fast Refresh by default. With Fast Refresh, as you make changes to `.svelte` files, Snowpack pushes live updates to the browser without losing your place or resetting component state. To see this for yourself, go ahead and add a simple timer to your App.svelte component. + +Svelte components include component specific scripts in a `<script>` tag. Add the counter here in `App.svelte` between the `<script>` tags: + +```html +<!-- src/App.svelte --> + +<script> + import { onMount } from 'svelte'; + let count = 0; + onMount(() => { + const interval = setInterval(() => count++, 1000); + return () => { + clearInterval(interval); + }; + }); +</script> +``` + +Then lower down in your component's body, add this code that displays the results of the timer. + +```diff +<!-- src/App.svelte --> + +<div class="App"> + <header class="App-header"> + <img src="/logo.svg" class="App-logo" alt="logo" /> ++ <p>Page has been open for <code>{count}</code> seconds.</p> + <a class="App-link" href="https://svelte.dev" target="_blank" rel="noopener noreferrer"> + Learn Svelte + </a> + </header> +</div> +``` + +Change some code on the page (like the "Learn Svelte" button). You'll see the timer does not reset. + +<div class="frame"><img src="/img/guides/svelte/svelte-snowpack-counter-1.gif" alt="Showing code and site side by side, when the word 'Hello' is added to the .svelte page and the code is saved, the change shows up in the browser without the timer resetting (it keeps counting)" class="screenshot"/></div> + +What about other, non-Svelte files like `src/index.js`? To re-render your Svelte application when other files change, add this code snippet to the bottom: + +```diff +<!-- src/index.js--> + +export default app; + ++// Hot Module Replacement (HMR) - Remove this snippet to remove HMR. ++// Learn more: https://www.snowpack.dev/concepts/hot-module-replacement ++if (import.meta.hot) { ++ import.meta.hot.accept(); ++ import.meta.hot.dispose(() => { ++ app.$destroy(); ++ }); ++} +``` + +## Going further + +Great job! You're now ready to build the Svelte project of your dreams with Snowpack. Want to tweet your accomplishment to the world? Click the button below: + +<a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-text="I just learned how to build a Svelte app with #Snowpack. Check out the tutorial:" data-show-count="false">Tweet</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script> + +At this point you have the basics and have a great starter for any Svelte project. The official [Snowpack Svelte](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/app-template-svelte) example has a few other tools you might find useful: + +- [Prettier](https://prettier.io/)—a popular code formatter + +- [Tests](/guides/testing)—Snowpack supports any popular JavaScript testing framework + +- [`@snowpack/plugin-dotenv`](https://github.com/snowpackjs/snowpack/tree/main/plugins/plugin-dotenv)—Use `dotenv` in your Snowpack. This is useful for environment specific variables + +We also recommend the official [Svelte](https://svelte.dev/tutorial/basics) tutorial, which teaches more about how Svelte works and how to build Svelte components. + +If you'd like to use Typescript with Snowpack and Svelte, check out the [Snowpack Svelte Typescript](https://github.com/snowpackjs/snowpack/tree/main/create-snowpack-app/app-template-svelte-typescript) template. + +If you have any questions, comments, or corrections, we'd love to hear from you in the Snowpack [discussion](https://github.com/snowpackjs/snowpack/discussions) forum or our [Snowpack Discord community](https://discord.gg/rS8SnRk). |