Skip to content

Latest commit

 

History

History
469 lines (364 loc) · 10.9 KB

b_dev.md

File metadata and controls

469 lines (364 loc) · 10.9 KB
< A) Directory Structure B) Dev > C) Build

This page explains how to use jsenv to start a development server for your source files.

Best parts of the jsenv dev server:

  • Standard web server: Complies with web standards, ensuring transparency and predictability.
  • Auto-reload on save: Automatically refreshes the browser when files are saved.
  • Error resilient: Remains functional even with syntax errors, allowing uninterrupted work.
  • Large browser support: Serves code compatible with majors browsers, including older versions.

Table of contents

  1. Usage
  2. Features

1. Usage

This section explains how to serve project source files using jsenv.

1.1 Project file structure

project/
  src/
    index.html
  package.json

src/index.html:

<!doctype html>
<html>
  <head>
    <title>Title</title>
    <meta charset="utf-8" />
    <link rel="icon" href="data:," />
  </head>

  <body>
    Hello world
  </body>
</html>

Add a dev.mjs file:

project/
+ scripts/
+    dev.mjs
  src/
    index.html
  package.json

scripts/dev.mjs:

import { startDevServer } from "@jsenv/core";

await startDevServer({
  sourceDirectoryUrl: new URL("../src/", import.meta.url),
});

1.2 Starting the server

a. Install dependencies:

npm i --save-dev @jsenv/core

b. Start the server

node ./scripts/dev.mjs

Expected output:

✔ start dev server (done in 0.009 second)
- http://localhost:3456
- http://127.0.0.1:3456

Title 2023-05-22 15-49-52

Figure: The development server in action, showing the served files and URLs

2. Features

2.1 Browser support

The dev server automatically serves the most compatible version of your code for the browser being used.

Supported browsers during development:

  • Chrome 64+
  • Safari 11.3+
  • Edge 79+
  • Firefox 67+
  • Opera 51+
  • Safari on IOS 12+
  • Samsung Internet 9.2+

Note: The browser support after the build process is broader, see browser support after build.

2.2 Directory structure agnostic

The dev server is compatible with any directory structure and does not impose assumptions. However, organizing source files into a dedicated directory is recommended for clarity.

Not ideal: Source files are mixed with other files.

project/
  node_modules/
    foo/
      foo.js
      package.json
  .gitignore
  index.html
  package.json

Better: Source files are in a separate directory.

project/
  node_modules/
    foo/
      foo.js
      package.json
  src/
    index.html
  .gitignore
  package.json

2.3 Root url equivalence

The root URL / is equivalent to /index.html:

http://localhost:3456 http://localhost:3456/index.html
title title

The main file can be configured with sourceMainFilePath:

import { startDevServer } from "@jsenv/core";

await startDevServer({
  sourceDirectoryUrl: new URL("../src/", import.meta.url),
  sourceMainFilePath: "./main.html",
});

2.4 ribbon

Without a visual marker it's hard to distinguish source files from build files.

dev server build server
title title

To differentiate source files from build files, the dev server injects a visual marker (ribbon) into HTML files:

ribbon screenshot

Figure: The ribbon in action, marking the page as served by the dev server

The code below shows how to disable the ribbon:

import { startDevServer } from "@jsenv/core";

await startDevServer({
  sourceDirectoryUrl: new URL("../src/", import.meta.url),
  ribbon: false, // Disables the ribbon
});

2.5 Error overlay

The dev server displays an error overlay when issues occur, complementing the browser’s dev tools:

image

Figure: The error overlay showing an error in the code.

Example HTML causing an error:

<!doctype html>
<html>
  <head>
    <title>Title</title>
    <meta charset="utf-8" />
    <link rel="icon" href="data:," />
  </head>

  <body>
    Hello world
    <script type="module" src="./main.js"></script>
  </body>
</html>

A lot of examples are available at tests/dev_server/errors/screenshots/.

Error overlay can be disabled as follow:

import { startDevServer } from "@jsenv/core";

await startDevServer({
  sourceDirectoryUrl: new URL("../src/", import.meta.url),
  supervisor: {
    errorOverlay: false, // Disables the error overlay
  },
});

In that case opening the same HTML file does not display error overlay. So devtools must be opened to see the error:

image

2.6 Autoreload

The dev server automatically applies changes when files are saved. Some updates can be applied without reloading the page, while others trigger a full reload.

TODO:

  • Explain what is "partial reload" + when it can be used (css for instance)
  • screenshots
  • explain import.meta.hot to unlock partial reload on js
  • Explain what is "full reload" + when it is used
  • screenshots

2.6.1 Configure autoreload

By default the following files can trigger a reload:

{
  "**/*": true, // All files inside the source directory
  "**/.*/": false, // Exclude directory starting with a dot
  "**/node_modules/": false, // Exclude node_modules
}

The following would change the files being watched:

import { startDevServer } from "@jsenv/core";

await startDevServer({
  sourceDirectoryUrl: new URL("../src/", import.meta.url),
  sourceFilesConfig: {
    "./**/*.js": true,
    "./**/*.css": false,
  },
});

2.6.2 Disable autoreload

import { startDevServer } from "@jsenv/core";

await startDevServer({
  sourceDirectoryUrl: new URL("../src/", import.meta.url),
  clientAutoreload: false,
});

2.7 Compatibility with frameworks

Enhance dev server capabilities with plugins. For example, to use React and JSX:

import { startDevServer } from "@jsenv/core";
import { jsenvPluginReact } from "@jsenv/plugin-react";

await startDevServer({
  sourceDirectoryUrl: new URL("../src/", import.meta.url),
  plugins: [jsenvPluginReact()],
});

See the full list of plugins in G) Plugins

2.8 sourcemaps

The dev server generates source mappings, helping browsers remap compiled code to its original source.

Value Description
"inline" Inline mappings as base64 in sourcemap comments.
"file" Generate separate .map files.
"none" Disable sourcemap generation.

Default: "inline"

2.9 port

The dev server defaults to port 3456. Change it as needed:

import { startDevServer } from "@jsenv/core";

await startDevServer({
  sourceDirectoryUrl: new URL("../src/", import.meta.url),
  port: 8888,
});

2.10 https

The dev server can use HTTPS with a certificate and private key:

import { startDevServer } from "@jsenv/core";

await startDevServer({
  sourceDirectoryUrl: new URL("../src/", import.meta.url),
  https: {
    certificate: "-----BEGIN CERTIFICATE-----...-----END CERTIFICATE-----",
    privateKey:
      "-----BEGIN RSA PRIVATE KEY-----...'-----END RSA PRIVATE KEY-----",
  },
});

Tip: Use @jsenv/https-local to generate certificates programmatically.

< A) Directory Structure B) Dev > C) Build