Coder Social home page Coder Social logo

plugin-json's Introduction

SystemJS

Gitter Backers on Open Collective Sponsors on Open Collective Downloads on JS Delivr

SystemJS is a hookable, standards-based module loader. It provides a workflow where code written for production workflows of native ES modules in browsers (like Rollup code-splitting builds), can be transpiled to the System.register module format to work in older browsers that don't support native modules, running almost-native module speeds while supporting top-level await, dynamic import, circular references and live bindings, import.meta.url, module types, import maps, integrity and Content Security Policy with compatibility in older browsers back to IE11.

Sponsors

Support SystemJS by becoming a sponsor. Your logo will show up here with a link to your website.

Backers

Thank you to all our backers! ๐Ÿ™ [Become a backer]

Overview

1. s.js minimal production loader

The minimal 2.8KB s.js production loader includes the following features:

  • Loads System.register modules, the CSP-compatible SystemJS module format.
  • Support for loading bare specifier names with import maps via <script type="systemjs-importmap">.
  • Supports hooks for loader customization.

2. system.js loader

The 4.2KB system.js loader adds the following features in addition to the s.js features above:

3. system-node.cjs loader

The system-node.cjs loader is a version of SystemJS build designed to run in Node.js, typically for workflows where System modules need to be executed on the server like SSR. It has the following features:

  • Loading System modules from disk (via file:// urls) or the network, with included caching that respects the Content-Type header.
  • Import Maps (via the applyImportMap api).
  • Tracing hooks and registry deletion API for reloading workflows.
  • Loading global modules with the included global loading extra.

Loading CommonJS modules is not currently supported in this loader and likely won't be. If you find you need them it is more advisable to use Node.js native module support where possible instead of the SystemJS Node.js loader.

Extras

The following pluggable extras can be dropped in with either the s.js or system.js loader:

  • AMD loading support (through Window.define which is created).
  • Named register supports System.register('name', ...) named bundles which can then be imported as System.import('name') (as well as AMD named define support)
  • Dynamic import maps support. This is currently a potential new standard feature.

The following extras are included in system.js loader by default, and can be added to the s.js loader for a smaller tailored footprint:

  • Global loading support for loading global scripts and detecting the defined global as the default export. Useful for loading common library scripts from CDN like System.import('//unpkg.com/lodash').
  • Module Types .css, .wasm, .json module type loading support in line with the existing modules specifications.

Since all loader features are hookable, custom extensions can be easily made following the same approach as the bundled extras. See the hooks documentation for more information.

SystemJS Babel

To support easy loading of TypeScript or ES modules in development SystemJS workflows, see the SystemJS Babel Extension.

SystemJS does not support direct integration with the native ES module browser loader because there is no way to share dependencies between the module systems. For extending the functionality of the native module loader in browsers, see ES module Shims, which like SystemJS, provides workflows for import maps and other modules features, but on top of base-level modules support in browsers, which it does using a fast Wasm-based source rewriting to remap module specifiers.

Performance

SystemJS is designed for production modules performance roughly only around a factor of 1.5 times the speed of native ES modules, as seen in the following performance benchmark, which was run by loading 426 javascript modules (all of @babel/core) on a Macbook pro with fast wifi internet connection. Each test was the average of five page loads in Chrome 80.

Tool Uncached Cached
Native modules 1668ms 49ms
SystemJS 2334ms 81ms

Getting Started

Introduction video.

The systemjs-examples repo contains a variety of examples demonstrating how to use SystemJS.

Installation

npm install systemjs

Documentation

Example Usage

Loading a System.register module

You can load System.register modules with a script element in your HTML:

<script src="system.js"></script>
<script type="systemjs-module" src="/js/main.js"></script>
<script type="systemjs-module" src="import:name-of-module"></script>

Loading with System.import

You can also dynamically load modules at any time with System.import():

System.import('/js/main.js');

where main.js is a module available in the System.register module format.

Bundling workflow

For an example of a bundling workflow, see the Rollup Code Splitting starter project - https://github.com/rollup/rollup-starter-code-splitting.

Note that when building System modules you typically want to ensure anonymous System.register statements like:

System.register([], function () { ... });

are emitted, as these can be loaded in a way that behaves the same as normal ES modules, and not named register statements like:

System.register('name', [], function () { ... });

While these can be supported with the named register extension, this approach is typically not recommended for modern modules workflows.

Import Maps

Say main.js depends on loading 'lodash', then we can define an import map:

<script src="system.js"></script>
<script type="systemjs-importmap">
{
  "imports": {
    "lodash": "https://unpkg.com/[email protected]/lodash.js"
  }
}
</script>
<!-- Alternatively:
<script type="systemjs-importmap" src="path/to/map.json" crossorigin="anonymous"></script>
-->
<script type="systemjs-module" src="/js/main.js"></script>

IE11 Support

IE11 continues to be fully supported, provided the relevant polyfills are available.

The main required polyfill is a Promise polyfill. If using import maps a fetch polyfill is also needed.

Both of these can be loaded conditionally using for example using Bluebird Promises and the GitHub Fetch Polyfill over Unpkg:

<script>
  if (typeof Promise === 'undefined')
    document.write('<script src="https://unpkg.com/[email protected]/js/browser/bluebird.core.min.js"><\/script>');
  if (typeof fetch === 'undefined')
    document.write('<script src="https://unpkg.com/[email protected]/dist/fetch.umd.js"><\/script>');
</script>

located before the SystemJS script itself. The above will ensure these polyfills are only fetched for older browsers without Promise and fetch support.

Note on Import Maps Support in IE11

When using external import maps (those with src="" attributes), there is an IE11-specific workaround that might need to be used. Browsers should not make a network request when they see <script type="systemjs-importmap" src="/importmap.json"></script> during parsing of the initial HTML page. However, IE11 does so. Codesandbox demonstration

Normally this is not an issue, as SystemJS will make an additional request via fetch/xhr for the import map. However, a problem can occur when the file is cached after the first request, since the first request caused by IE11 does not send the Origin request header by default. If the request requires CORS, the lack of an Origin request header causes many web servers (including AWS Cloudfront) to omit the response CORS headers. This can result in the resource being cached without CORS headers, which causes the later SystemJS fetch() to fail because of CORS checks.

This can be worked around by adding crossorigin="anonymous" as an attribute to the <script type="systemjs-importmap"> script.

Community Projects

A list of projects that use or work with SystemJS in providing modular browser workflows. Post a PR.

  • beyondjs.com -TypeScript first meta-framework for universal microfrontends/micronservices.
  • esm-bundle - list of System.register versions for major libraries, including documentation on how to create a System.register bundle for any npm package.
  • es-dev-server - A web server for developing without a build step.
  • import map overrides - Dynamically inject an import map stored in local storage so that you can override the URL for any module. Can be useful for running development modules on localhost against the server.
  • js-env - Collection of development tools providing a unified workflow to write JavaScript for the web, node.js or both at the same time.
  • jspm.org - Package manager for native modules, using SystemJS for backwards compatibility.
  • single-spa - JavaScript framework for front-end microservices.
  • systemjs-webpack-interop - npm lib for setting webpack public path and creating webpack configs that work well with SystemJS.
  • @wener/system - hooks to make System works with npm registry & package.json}

Compatibility with Webpack

Code-splitting builds on top of native ES modules, like Rollup offers, are an alternative to the Webpack-style chunking approach - offering a way to utilize the native module loader for loading shared and dynamic chunks instead of using a custom registry and loader as Webpack bundles include. Scope-level optimizations can be performed on ES modules when they are combined, while ensuring no duplicate code is loaded through dynamic loading and code-sharing in the module registry, using the features of the native module loader and its dynamic runtime nature.

systemjs-webpack-interop is a community-maintained npm library that might help you get webpack and systemjs working well together.

As of [email protected], it is now possible to compile webpack bundles to System.register format, by modifying your webpack config:

{
  output: {
    libraryTarget: 'system', 
  }
}

If using webpack@<5, the following config is needed to avoid rewriting references to the global System variable:

{
  module: {
    rules: [
      { parser: { system: false } }
    ]
  }
}

Using npm packages

Third party libraries and npm packages may be used as long as they are published in a supported module format. For packages that do not exist in a supported module format, here is a list of github repos that publish System.register versions of popular third party libraries (such as react, react-dom, rxjs, etc).

Contributing to SystemJS

Project bug fixes and changes are welcome for discussion, provided the project footprint remains minimal.

Task running is handled by Chomp (https://chompbuild.com).

To run the tests:

npm install -g chomp
chomp test

Changes

For the changelog, see CHANGELOG.md.

License

MIT

plugin-json's People

Contributors

fabioelia avatar guybedford avatar hypercubed avatar jperals avatar mk-pmb avatar pvnr0082t avatar sergei-startsev avatar unional avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

plugin-json's Issues

importing the json loader causes execution to fail silently!

I think this is a bug but may be I am wrong?? If I do something like:

import 'json'

the page loading (systemjs loading import file) stops somewhere in between and there is no error message. I once waited really long to get a timeout but have not been able to reproduce this. I don't know what other helpful information I can provide...

I already import css and html like this without problems. The reason I am doing this is that I want to keep some json files outside the bundle which the user can configure by hand before loading the page (I am using nwjs, so the user has access to the files).

JSPM 0.16.53

0.2.0 incompatible with rollup

When building a static build with rollup optimizations, rollup is unable to detect named exports from .json files. This works fine if the json plugin is downgraded to 0.1.0.

.js extension is added when loading json file

While trying to load a file like so: import myJson from '/test/mocks/my-json!json'; or like so: import myJson from '/test/mocks/my-json.json'; The loader is adding the .js extension in the end of request while doing import. Wha I get form phantom in the concole is something like this:

Error loading http://localhost:9877/test/mocks/my-json.json.js as "/test/mocks/my-json.json" 

Currently using: "json": "github:systemjs/[email protected]", with jspm version 0.16.14.

Is there anything I'm missing? Thanks!

Convert to commonjs format

I'm working on the plugin system as described in systemjs/systemjs#1528

It is progressing well. ๐Ÿ˜

One issue arise is to load the package.json or any resources in the plugin that requires a loader.

Using package.json as an example, the host SystemJS needs to use the json.js loader.

However, I don't want require the host to define and rely on systemjs.config.js (or jspm with jspm.config.js for that matter) and let SystemJS to load the config and subsequently load the loader dynamically.

I use SystemJS.set('json.js', SystemJS.newModule(jsonLoader)) to pre-load and register the loader.

I have tested and it is working, however I have to convert the json.js in this repo to commonjs format so that I can use it directly in the code.

If I don't, it will fail as define() is not defined in NodeJS.

Since this repo is published as systemjs-plugin-json in npm, we should be able to load it in NodeJS. ๐Ÿ˜›

Here is the converted code (written in TypeScript without any type. ๐Ÿ˜œ ):

// this code allows named exports of valid identifiers in json to work with rollup
// so you can effectively "pick" a json value and have the other base-level json values excluded
// not comprehensive of course
function isValidIdentifier(exportName) {
  return exportName.match(/^[a-zA-Z_$][0-9a-zA-Z_$]*$/);
}

export const jsonLoader = {
  translate: function (load) {
    const json = JSON.parse(load.source);
    if (this.builder && this.transpiler && !Array.isArray(json)) {
      load.metadata.format = 'esm';

      const namedExports = Object.keys(json);
      const validIdentifiers = namedExports.filter(isValidIdentifier);

      const output = ['exp' + 'ort var __useDefault = true;\n'];

      validIdentifiers.forEach(function (exportName) {
        output.push('exp' + 'ort var ' + exportName + ' = ' + JSON.stringify(json[exportName]) + ';\n');
      });

      output.push('exp' + 'ort default {\n');
      namedExports.forEach(function (exportName) {
        if (validIdentifiers.indexOf(exportName) !== -1) {
          output.push(exportName + ': ' + exportName + ',\n');
        }
        else {
          output.push(JSON.stringify(exportName) + ': ' + JSON.stringify(json[exportName]) + ',\n');
        }
      });

      output.push('};');

      return output.join('');
    }
    if (this.builder) {
      load.metadata.format = 'cjs';
      return 'module.exports = ' + JSON.stringify(json);
    }
  },
  instantiate: function (load) {
    if (!this.builder) {
      return JSON.parse(load.source);
    }
  }
}

Please configure package.json and register this as npm package.

The projects that I am working on are moving away from bower and attempting to reliy entirely on npm for external dependencies. This is prefaced by the AngularJS team moving their stuff to the npm registry.

Please make this an npm package and register it so we can make use of it from npm and not bower.

Thank you

systemjs-plugin-json cause infinity loading

I require a way to load *.json via SystemJS. For this I add the following lines to my systemjs config:

System.config({ 
   'meta': { 
      '*.json': { loader: 'systemjs-plugin-json' } 
   },
   'path': {
      'app': 'app',
      'systemjs-plugin-json': 'node_modules/systemjs-plugin-json/json.js',
   }
});

Without the statement "meta": { '*.json': { loader: 'systemjs-plugin-json' } } everything works fine, but after adding this line the webapplication runs into a infinity loop (browser doesn't complete loading, the application allocate a lot of memory).

Here I add the full config: systemjs.config.lineAndIngest.zip

Could anyone help me with this problem?

Thanks!

`npm test` broken

It seems that having moved the test files into the test directory broke the npm test command.
Moving them back to the root works as a workaround, even though it might be better to make changes to the npm test command and/or to the corresponding files.

Installation failure?

Just starting a new project tonight, this happened:

image

Don't have time to follow it down right now, but didn't want to leave it unreported either. Can look into it further if you need me to.

Attempting to import json file in jspm/typescript project results in error TS2307

Hi,

I'm building a Typescript project using jspm in Webstorm. I'm a newbie to web dev, so I could very easily be missing something obvious here.

I ran jspm install json in my project, which seemed to work fine. It appears under dependencies in package.json.

When I try to include a json file in a .ts file in my project, I get Error TS2307 - Cannot find module.

The import statement is
import Data from "../data/data.json!";

I've also tried

import Data from "../data/data.json!json";

But that didn't work either.

import "../data/data.json!"; works but as near as I can figure won't actually do anything.

The folder structure of my project:

app
--source
----data
------data.json
----[another folder]
------.ts source file attempting to include data.json
config.js
package.json
etc

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.