├── public ├── .gitignore ├── favicon.png ├── jOzrELAzFxtMx2I4uDGHOotdfsS.jpg └── index.html ├── tailwind.base.css ├── .gitignore ├── markup ├── Components.png ├── Svelte Store.jpg ├── jOzrELAzFxtMx2I4uDGHOotdfsS.jpg ├── object.json └── index.html ├── postcss.config.js ├── src ├── App.svelte ├── main.js ├── api │ ├── http.js │ └── movie-api.js ├── features │ └── Movies │ │ ├── Movies.svelte │ │ ├── Movies.spec.js │ │ ├── MovieCard.svelte │ │ ├── MovieList.svelte │ │ ├── MovieCard.spec.js │ │ ├── MovieSearch.spec.js │ │ ├── MovieSearch.svelte │ │ └── MovieList.spec.js ├── store │ └── index.js └── mocks │ └── movie.json ├── tailwind.config.js ├── package.json ├── rollup.config.js └── README.md /public/.gitignore: -------------------------------------------------------------------------------- 1 | .now -------------------------------------------------------------------------------- /tailwind.base.css: -------------------------------------------------------------------------------- 1 | @tailwind base; 2 | @tailwind components; 3 | @tailwind utilities; 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules/ 2 | /public/build/ 3 | /public/index.css 4 | 5 | .DS_Store 6 | -------------------------------------------------------------------------------- /public/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vedovelli/curso-svelte/HEAD/public/favicon.png -------------------------------------------------------------------------------- /markup/Components.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vedovelli/curso-svelte/HEAD/markup/Components.png -------------------------------------------------------------------------------- /markup/Svelte Store.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vedovelli/curso-svelte/HEAD/markup/Svelte Store.jpg -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | plugins: [require("tailwindcss")("./tailwind.config.js")], 3 | }; 4 | -------------------------------------------------------------------------------- /src/App.svelte: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /markup/jOzrELAzFxtMx2I4uDGHOotdfsS.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vedovelli/curso-svelte/HEAD/markup/jOzrELAzFxtMx2I4uDGHOotdfsS.jpg -------------------------------------------------------------------------------- /public/jOzrELAzFxtMx2I4uDGHOotdfsS.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/vedovelli/curso-svelte/HEAD/public/jOzrELAzFxtMx2I4uDGHOotdfsS.jpg -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | // https://github.com/sveltemaster/svelte-unit-tests 2 | import App from "./App.svelte"; 3 | 4 | const app = new App({ 5 | target: document.body, 6 | }); 7 | 8 | export default app; 9 | -------------------------------------------------------------------------------- /src/api/http.js: -------------------------------------------------------------------------------- 1 | import axios from "axios"; 2 | 3 | export const API_KEY = "a1279933de606b4374a2c93a1d0127a9"; 4 | 5 | export const http = axios.create({ 6 | baseURL: "https://api.themoviedb.org/3/search/", 7 | }); 8 | -------------------------------------------------------------------------------- /tailwind.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | purge: { 3 | enabled: process.env.NODE_ENV === "production", 4 | content: ["./public/index.html", "./src/**/*.svelte"], 5 | }, 6 | theme: { 7 | extend: {}, 8 | }, 9 | variants: {}, 10 | plugins: [require("@tailwindcss/ui")], 11 | }; 12 | -------------------------------------------------------------------------------- /src/features/Movies/Movies.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 |
9 |
10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /src/features/Movies/Movies.spec.js: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom/extend-expect"; 2 | import { render } from "@testing-library/svelte"; 3 | import Movies from "../Movies/Movies.svelte"; 4 | 5 | describe("Movies", () => { 6 | it("mounts MovieSearch and MovieList", () => { 7 | const { getByTestId } = render(Movies); 8 | 9 | expect(getByTestId("movie-search")).toBeInTheDocument(); 10 | expect(getByTestId("movie-list")).toBeInTheDocument(); 11 | }); 12 | }); 13 | -------------------------------------------------------------------------------- /src/store/index.js: -------------------------------------------------------------------------------- 1 | import { writable, derived } from "svelte/store"; 2 | 3 | export const INITIAL_STATE = { 4 | movies: [], 5 | wasSearched: false, 6 | }; 7 | 8 | export const store = writable({ ...INITIAL_STATE }); 9 | 10 | export const movies = derived(store, (store) => { 11 | return store.movies 12 | .filter((movie) => movie.backdrop_path != null) 13 | .map((movie) => { 14 | movie.friendly_date = new Date(movie.release_date).toLocaleDateString(); 15 | return movie; 16 | }); 17 | }); 18 | -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | Svelte app 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/api/movie-api.js: -------------------------------------------------------------------------------- 1 | import { API_KEY, http } from "./http"; 2 | import { INITIAL_STATE, store } from "../store"; 3 | 4 | export const BACKDROP_BASE_URL = "https://image.tmdb.org/t/p/original"; 5 | 6 | export const fetchMovies = async (term) => { 7 | const { 8 | data: { results: movies }, 9 | } = await http.get(`movie?api_key=${API_KEY}&query=${term}`); 10 | 11 | store.set({ 12 | ...INITIAL_STATE, 13 | movies, 14 | wasSearched: true, 15 | }); 16 | }; 17 | 18 | export const resetMovies = () => { 19 | store.set({ 20 | ...INITIAL_STATE, 21 | }); 22 | }; 23 | -------------------------------------------------------------------------------- /markup/object.json: -------------------------------------------------------------------------------- 1 | { 2 | "popularity": 35.415, 3 | "vote_count": 18207, 4 | "video": false, 5 | "poster_path": "/d5iIlFn5s0ImszYzBPb8JPIfbXD.jpg", 6 | "id": 680, 7 | "adult": false, 8 | "backdrop_path": "/suaEOtk1N1sgg2MTM7oZd2cfVp3.jpg", 9 | "original_language": "en", 10 | "original_title": "Pulp Fiction", 11 | "genre_ids": [80, 53], 12 | "title": "Pulp Fiction", 13 | "vote_average": 8.5, 14 | "overview": "A burger-loving hit man, his philosophical partner, a drug-addled gangster's moll and a washed-up boxer converge in this sprawling, comedic crime caper. Their adventures unfurl in three stories that ingeniously trip back and forth in time.", 15 | "release_date": "1994-09-10" 16 | } 17 | -------------------------------------------------------------------------------- /src/features/Movies/MovieCard.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
8 |
9 | {`Poster: 14 |
15 |
16 |
18 | {movie.title} 19 |
20 |
21 |

22 | Avaliação: 23 | {movie.vote_average} 24 | com {movie.vote_count} votos 25 |

26 |

Lançamento: {movie.friendly_date}

27 |
28 |

{movie.overview}

29 |
30 |
31 |
32 | -------------------------------------------------------------------------------- /src/features/Movies/MovieList.svelte: -------------------------------------------------------------------------------- 1 | 10 | 11 |
12 |
13 | {#if $store.wasSearched && !$movies.length} 14 |

15 | Nenhum filme encontrado 16 |

17 | {/if} 18 | {#if $movies.length} 19 |
    24 | {#each $movies as movie} 25 |
  • 30 | 31 |
  • 32 | {/each} 33 |
34 | {/if} 35 |
36 |
37 | -------------------------------------------------------------------------------- /src/features/Movies/MovieCard.spec.js: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom/extend-expect"; 2 | import { render } from "@testing-library/svelte"; 3 | import MovieCard from "../Movies/MovieCard.svelte"; 4 | import moviesMock from "../../mocks/movie.json"; 5 | 6 | describe("MovieCard", () => { 7 | it("renders the movie poster with proper data", () => { 8 | const [movie] = moviesMock.results; 9 | 10 | const { getByAltText } = render(MovieCard, { movie }); 11 | 12 | const image = getByAltText(`Poster: ${movie.title}`); 13 | 14 | expect(image).toBeInTheDocument(); 15 | expect(image).toHaveProperty( 16 | "src", 17 | "https://image.tmdb.org/t/p/original/kaPTm06WnoqaHOgGbQaRCrupaKo.jpg" 18 | ); 19 | }); 20 | 21 | it("renders movie card with all relevant content", () => { 22 | const [movie] = moviesMock.results; 23 | 24 | movie.friendly_date = new Date(movie.release_date).toLocaleDateString(); 25 | 26 | const { getByText } = render(MovieCard, { movie }); 27 | 28 | expect(getByText("Men in Black")).toBeInTheDocument(); 29 | 30 | const exactAssertions = [ 31 | "com 9337 votos", 32 | "7.1", 33 | "7/2/1997", 34 | "and new recruit Agent Jay", 35 | ]; 36 | 37 | exactAssertions.forEach((item) => { 38 | expect(getByText(item, { exact: false })).toBeInTheDocument(); 39 | }); 40 | }); 41 | }); 42 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "svelte-app", 3 | "version": "1.0.0", 4 | "scripts": { 5 | "watch:tailwind": "postcss tailwind.base.css -o public/index.css", 6 | "build:tailwind": "NODE_ENV=production postcss tailwind.base.css -o public/index.css", 7 | "build": "yarn build:tailwind && rollup -c", 8 | "dev": "yarn watch:tailwind && rollup -c -w", 9 | "start": "sirv public", 10 | "test": "jest src --watchAll" 11 | }, 12 | "devDependencies": { 13 | "@babel/core": "^7.9.6", 14 | "@babel/preset-env": "^7.9.6", 15 | "@rollup/plugin-commonjs": "^11.0.0", 16 | "@rollup/plugin-node-resolve": "^7.0.0", 17 | "@tailwindcss/ui": "^0.3.0", 18 | "@testing-library/jest-dom": "^5.5.0", 19 | "@testing-library/svelte": "^3.0.0", 20 | "axios": "^0.19.2", 21 | "babel-jest": "^25.5.1", 22 | "jest": "^25.5.3", 23 | "postcss-cli": "^7.1.1", 24 | "rollup": "^1.20.0", 25 | "rollup-plugin-livereload": "^1.0.0", 26 | "rollup-plugin-svelte": "^5.0.3", 27 | "rollup-plugin-terser": "^5.1.2", 28 | "svelte": "^3.0.0", 29 | "svelte-jester": "^1.0.5", 30 | "tailwindcss": "^1.4.4" 31 | }, 32 | "dependencies": { 33 | "sirv-cli": "^0.4.4" 34 | }, 35 | "jest": { 36 | "bail": false, 37 | "moduleFileExtensions": [ 38 | "js", 39 | "svelte" 40 | ], 41 | "transform": { 42 | "^.+\\.js$": "babel-jest", 43 | "^.+\\.svelte$": "svelte-jester" 44 | }, 45 | "verbose": true 46 | }, 47 | "babel": { 48 | "presets": [ 49 | [ 50 | "@babel/preset-env", 51 | { 52 | "targets": { 53 | "node": "current" 54 | } 55 | } 56 | ] 57 | ] 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /src/features/Movies/MovieSearch.spec.js: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom/extend-expect"; 2 | import { render, fireEvent } from "@testing-library/svelte"; 3 | import MovieSearch from "../Movies/MovieSearch.svelte"; 4 | jest.mock("../../api/movie-api"); 5 | import { fetchMovies, resetMovies } from "../../api/movie-api"; 6 | import { store, INITIAL_STATE } from "../../store"; 7 | 8 | describe("MovieSearch", () => { 9 | afterEach(() => { 10 | jest.resetAllMocks(); 11 | }); 12 | 13 | it("renders a form control", () => { 14 | const { getByTestId } = render(MovieSearch); 15 | 16 | expect(getByTestId("search-form")).toBeInTheDocument(); 17 | }); 18 | 19 | it("renders an input control", () => { 20 | const { getByTestId } = render(MovieSearch); 21 | 22 | expect(getByTestId("search-input")).toBeInTheDocument(); 23 | }); 24 | 25 | it("executes fetchMovies when form is submitted", async () => { 26 | const { getByTestId } = render(MovieSearch); 27 | 28 | const form = getByTestId("search-form"); 29 | const input = getByTestId("search-input"); 30 | 31 | await fireEvent.input(input, { target: { value: "men" } }); 32 | await fireEvent.submit(form); 33 | 34 | expect(fetchMovies).toHaveBeenCalledTimes(1); 35 | expect(fetchMovies).toHaveBeenCalledWith("men"); 36 | }); 37 | 38 | it("executes resetMovies when term is cleared after being something else than empty string", async () => { 39 | store.set({ 40 | ...INITIAL_STATE, 41 | wasSearched: true, 42 | }); 43 | 44 | const { getByTestId } = render(MovieSearch); 45 | 46 | const input = getByTestId("search-input"); 47 | 48 | await fireEvent.input(input, { target: { value: "men" } }); 49 | await fireEvent.input(input, { target: { value: "" } }); 50 | 51 | expect(resetMovies).toHaveBeenCalledTimes(2); 52 | }); 53 | }); 54 | -------------------------------------------------------------------------------- /rollup.config.js: -------------------------------------------------------------------------------- 1 | import svelte from 'rollup-plugin-svelte'; 2 | import resolve from '@rollup/plugin-node-resolve'; 3 | import commonjs from '@rollup/plugin-commonjs'; 4 | import livereload from 'rollup-plugin-livereload'; 5 | import { terser } from 'rollup-plugin-terser'; 6 | 7 | const production = !process.env.ROLLUP_WATCH; 8 | 9 | export default { 10 | input: 'src/main.js', 11 | output: { 12 | sourcemap: true, 13 | format: 'iife', 14 | name: 'app', 15 | file: 'public/build/bundle.js' 16 | }, 17 | plugins: [ 18 | svelte({ 19 | // enable run-time checks when not in production 20 | dev: !production, 21 | // we'll extract any component CSS out into 22 | // a separate file - better for performance 23 | css: css => { 24 | css.write('public/build/bundle.css'); 25 | } 26 | }), 27 | 28 | // If you have external dependencies installed from 29 | // npm, you'll most likely need these plugins. In 30 | // some cases you'll need additional configuration - 31 | // consult the documentation for details: 32 | // https://github.com/rollup/plugins/tree/master/packages/commonjs 33 | resolve({ 34 | browser: true, 35 | dedupe: ['svelte'] 36 | }), 37 | commonjs(), 38 | 39 | // In dev mode, call `npm run start` once 40 | // the bundle has been generated 41 | !production && serve(), 42 | 43 | // Watch the `public` directory and refresh the 44 | // browser on changes when not in production 45 | !production && livereload('public'), 46 | 47 | // If we're building for production (npm run build 48 | // instead of npm run dev), minify 49 | production && terser() 50 | ], 51 | watch: { 52 | clearScreen: false 53 | } 54 | }; 55 | 56 | function serve() { 57 | let started = false; 58 | 59 | return { 60 | writeBundle() { 61 | if (!started) { 62 | started = true; 63 | 64 | require('child_process').spawn('npm', ['run', 'start', '--', '--dev'], { 65 | stdio: ['ignore', 'inherit', 'inherit'], 66 | shell: true 67 | }); 68 | } 69 | } 70 | }; 71 | } 72 | -------------------------------------------------------------------------------- /src/features/Movies/MovieSearch.svelte: -------------------------------------------------------------------------------- 1 | 15 | 16 |
17 |
21 |
22 |
24 | 28 | 31 | 32 |
33 | 39 |
40 | 52 |
53 |
54 | -------------------------------------------------------------------------------- /src/mocks/movie.json: -------------------------------------------------------------------------------- 1 | { 2 | "page": 1, 3 | "total_results": 3807, 4 | "total_pages": 191, 5 | "results": [ 6 | { 7 | "popularity": 32.857, 8 | "vote_count": 9337, 9 | "video": false, 10 | "poster_path": "/uLOmOF5IzWoyrgIF5MfUnh5pa1X.jpg", 11 | "id": 607, 12 | "adult": false, 13 | "backdrop_path": "/kaPTm06WnoqaHOgGbQaRCrupaKo.jpg", 14 | "original_language": "en", 15 | "original_title": "Men in Black", 16 | "genre_ids": [28, 12, 35, 878], 17 | "title": "Men in Black", 18 | "vote_average": 7.1, 19 | "overview": "After a police chase with an otherworldly being, a New York City cop is recruited as an agent in a top-secret organization established to monitor and police alien activity on Earth: the Men in Black. Agent Kay and new recruit Agent Jay find themselves in the middle of a deadly plot by an intergalactic terrorist who has arrived on Earth to assassinate two ambassadors from opposing galaxies.", 20 | "release_date": "1997-07-02" 21 | }, 22 | { 23 | "popularity": 29.232, 24 | "vote_count": 9372, 25 | "video": false, 26 | "poster_path": "/qttNmCib9gHhR5q0QoZ3FgmGom9.jpg", 27 | "id": 246655, 28 | "adult": false, 29 | "backdrop_path": "/2ex2beZ4ssMeOduLD0ILzXKCiep.jpg", 30 | "original_language": "en", 31 | "original_title": "X-Men: Apocalypse", 32 | "genre_ids": [28, 12, 14, 878], 33 | "title": "X-Men: Apocalypse", 34 | "vote_average": 6.5, 35 | "overview": "After the re-emergence of the world's first mutant, world-destroyer Apocalypse, the X-Men must unite to defeat his extinction level plan.", 36 | "release_date": "2016-05-18" 37 | }, 38 | { 39 | "popularity": 29.232, 40 | "vote_count": 9372, 41 | "video": false, 42 | "poster_path": "/qttNmCib9gHhR5q0QoZ3FgmGom9.jpg", 43 | "id": 246658, 44 | "adult": false, 45 | "backdrop_path": null, 46 | "original_language": "en", 47 | "original_title": "X-Men: Apocalypse", 48 | "genre_ids": [28, 12, 14, 878], 49 | "title": "X-Men: Apocalypse", 50 | "vote_average": 6.5, 51 | "overview": "After the re-emergence of the world's first mutant, world-destroyer Apocalypse, the X-Men must unite to defeat his extinction level plan.", 52 | "release_date": "2016-05-18" 53 | } 54 | ] 55 | } 56 | -------------------------------------------------------------------------------- /src/features/Movies/MovieList.spec.js: -------------------------------------------------------------------------------- 1 | import "@testing-library/jest-dom/extend-expect"; 2 | import { render, fireEvent } from "@testing-library/svelte"; 3 | import MovieList from "../Movies/MovieList.svelte"; 4 | import { store, INITIAL_STATE } from "../../store"; 5 | import moviesMock from "../../mocks/movie.json"; 6 | 7 | const setStore = ({ movies }) => { 8 | store.set({ 9 | ...INITIAL_STATE, 10 | wasSearched: true, 11 | movies, 12 | }); 13 | }; 14 | 15 | describe("MovieList", () => { 16 | it("renders a message when a search was made and no movies are returned", () => { 17 | setStore({ movies: [] }); 18 | 19 | const { getByText } = render(MovieList); 20 | 21 | expect(getByText("Nenhum filme encontrado")).toBeInTheDocument(); 22 | }); 23 | 24 | it("renders movie list when a search was made and movies are returned", () => { 25 | setStore({ movies: moviesMock.results }); 26 | 27 | const { getByTestId } = render(MovieList); 28 | 29 | expect(getByTestId("movie-list")).toBeInTheDocument(); 30 | }); 31 | 32 | it("renders movie list with 2 movies even when the list contains more movies but only 2 of them contain backdrop_path", () => { 33 | setStore({ movies: moviesMock.results }); 34 | 35 | const { getByTestId } = render(MovieList); 36 | 37 | expect(getByTestId("movie-list")).toBeInTheDocument(); 38 | }); 39 | 40 | it("select a movie card when a movie item gets clicked", async () => { 41 | setStore({ movies: moviesMock.results }); 42 | 43 | const { getAllByTestId } = render(MovieList); 44 | 45 | const card = getAllByTestId("movie-item")[0]; 46 | 47 | await fireEvent.click(card); 48 | 49 | expect(card).toHaveClass("bg-red-200"); 50 | }); 51 | 52 | it("toggles card selection when a card is clicked a second time", async () => { 53 | setStore({ movies: moviesMock.results }); 54 | 55 | const { getAllByTestId } = render(MovieList); 56 | 57 | const card = getAllByTestId("movie-item")[0]; 58 | 59 | await fireEvent.click(card); 60 | expect(card).toHaveClass("bg-red-200"); 61 | 62 | await fireEvent.click(card); 63 | expect(card).not.toHaveClass("bg-red-200"); 64 | }); 65 | 66 | it("removes select from the first clicked card when a second card is clicked", async () => { 67 | setStore({ movies: moviesMock.results }); 68 | 69 | const { getAllByTestId } = render(MovieList); 70 | 71 | const [card1, card2] = getAllByTestId("movie-item"); 72 | 73 | await fireEvent.click(card1); 74 | expect(card1).toHaveClass("bg-red-200"); 75 | expect(card2).not.toHaveClass("bg-red-200"); 76 | 77 | await fireEvent.click(card2); 78 | expect(card1).not.toHaveClass("bg-red-200"); 79 | expect(card2).toHaveClass("bg-red-200"); 80 | }); 81 | }); 82 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Curso de Svelte do Vedovelli 2 | 3 | Este repositório contém o código-fonte escrito durante o curso de Svelte. O curso é gratuito e pode ser acessado aqui: https://classes.vedovelli.com.br/?class=curso-de-svelte-introducao 4 | 5 | --- 6 | 7 | *Looking for a shareable component template? Go here --> [sveltejs/component-template](https://github.com/sveltejs/component-template)* 8 | 9 | --- 10 | 11 | # svelte app 12 | 13 | This is a project template for [Svelte](https://svelte.dev) apps. It lives at https://github.com/sveltejs/template. 14 | 15 | To create a new project based on this template using [degit](https://github.com/Rich-Harris/degit): 16 | 17 | ```bash 18 | npx degit sveltejs/template svelte-app 19 | cd svelte-app 20 | ``` 21 | 22 | *Note that you will need to have [Node.js](https://nodejs.org) installed.* 23 | 24 | 25 | ## Get started 26 | 27 | Install the dependencies... 28 | 29 | ```bash 30 | cd svelte-app 31 | npm install 32 | ``` 33 | 34 | ...then start [Rollup](https://rollupjs.org): 35 | 36 | ```bash 37 | npm run dev 38 | ``` 39 | 40 | Navigate to [localhost:5000](http://localhost:5000). You should see your app running. Edit a component file in `src`, save it, and reload the page to see your changes. 41 | 42 | By default, the server will only respond to requests from localhost. To allow connections from other computers, edit the `sirv` commands in package.json to include the option `--host 0.0.0.0`. 43 | 44 | 45 | ## Building and running in production mode 46 | 47 | To create an optimised version of the app: 48 | 49 | ```bash 50 | npm run build 51 | ``` 52 | 53 | You can run the newly built app with `npm run start`. This uses [sirv](https://github.com/lukeed/sirv), which is included in your package.json's `dependencies` so that the app will work when you deploy to platforms like [Heroku](https://heroku.com). 54 | 55 | 56 | ## Single-page app mode 57 | 58 | By default, sirv will only respond to requests that match files in `public`. This is to maximise compatibility with static fileservers, allowing you to deploy your app anywhere. 59 | 60 | If you're building a single-page app (SPA) with multiple routes, sirv needs to be able to respond to requests for *any* path. You can make it so by editing the `"start"` command in package.json: 61 | 62 | ```js 63 | "start": "sirv public --single" 64 | ``` 65 | 66 | 67 | ## Deploying to the web 68 | 69 | ### With [now](https://zeit.co/now) 70 | 71 | Install `now` if you haven't already: 72 | 73 | ```bash 74 | npm install -g now 75 | ``` 76 | 77 | Then, from within your project folder: 78 | 79 | ```bash 80 | cd public 81 | now deploy --name my-project 82 | ``` 83 | 84 | As an alternative, use the [Now desktop client](https://zeit.co/download) and simply drag the unzipped project folder to the taskbar icon. 85 | 86 | ### With [surge](https://surge.sh/) 87 | 88 | Install `surge` if you haven't already: 89 | 90 | ```bash 91 | npm install -g surge 92 | ``` 93 | 94 | Then, from within your project folder: 95 | 96 | ```bash 97 | npm run build 98 | surge public my-project.surge.sh 99 | ``` 100 | -------------------------------------------------------------------------------- /markup/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | Document 11 | 12 | 13 |
14 |
15 |
16 |
17 |
20 |
21 |
24 | 29 | 33 | 34 |
35 | 40 |
41 | 56 |
57 |
58 |
59 |
60 |

63 | Nenhum filme encontrado 64 |

65 |
    66 |
  • 69 |
    70 |
    71 |
    72 | Woman paying for a purchase 78 |
    79 |
    80 |
    83 | STAR WARS: THE RISE OF SKYWALKER 84 |
    85 |
    88 |

    89 | Avaliação: 90 | 6.5 91 | com 3834 votos 92 |

    93 |

    94 | Lançamento: 18/12/2019 95 |

    96 |
    97 |

    98 | The surviving Resistance faces the First Order once 99 | again as the journey of Rey, Finn and Poe Dameron 100 | continues. With the power and knowledge of generations 101 | behind them, the final battle begins. 102 |

    103 |
    104 |
    105 |
    106 |
  • 107 |
  • 110 |
    111 |
    112 |
    113 | Woman paying for a purchase 119 |
    120 |
    121 |
    124 | STAR WARS: THE RISE OF SKYWALKER 125 |
    126 |
    129 |

    130 | Avaliação: 131 | 6.5 132 | com 3834 votos 133 |

    134 |

    135 | Lançamento: 18/12/2019 136 |

    137 |
    138 |

    139 | The surviving Resistance faces the First Order once 140 | again as the journey of Rey, Finn and Poe Dameron 141 | continues. With the power and knowledge of generations 142 | behind them, the final battle begins. 143 |

    144 |
    145 |
    146 |
    147 |
  • 148 |
149 |
150 |
151 |
152 |
153 |
154 | 155 | 156 | --------------------------------------------------------------------------------