mockingbot / json-compact-loader

Replace big named export value to 'JSON.parse(...)'

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

json-compact-loader

i:npm i:ci i:size i:npm-dev

Replace big named export value to 'JSON.parse(...)'

  • 📁 source/
    • source code, in output package will be: json-compact-loader/library
  • 📁 test/
    • basic test with webpack, run with npm run test-webpack or npm run test-webpack-watch

Why a special JSON loader

Using JSON as data source in JS is quite common, but the JSON format is not flexible enough for development. So often we unpack the JSON String to plain JS Objects, now we got comments, data-generate-functions, and best of all: 2 more quote to choose!

But there's a catch, a few actually:

  • It's JS, so it's heavier to parse in code, check: https://www.youtube.com/watch?v=ff4fgQxPaO0 and webpack/webpack#9349
  • When the package is prepared for bigger project, the "huge" JSON String actually cost far less performance problems, since the AST for a String is far simpler than a deep-nested Object. Common build tools like babel, webpack/rollup, terser/uglifyjs should also parse and repack your code faster.

This loader allows the JSON data in output as JSON.parse(...), while keeping the source code easy to edit as JS.

This loader should support webpack v5 and v4 with nodejs 12+.

The limitation

Sad, but there's some limit to what the code can do:

  • the file naming should be NAME_OF_JSON.@json.js, and the NAME_OF_JSON should be basic /[\w-]+/, to also be usable as variable name
  • the file can only have single named export, should be NAME_OF_JSON, or simply file should just end with export { NAME_OF_JSON }
  • data generation with code is supported, but only further import of .js/json is allowed, no require for now, this is because webpack need to know the related file, but require is hard to parse correctly

That's it, note the .@json.js suffix is recommended, but not required, change it to something else if needed.

How to use

With source like:

// file: `SAMPLE_JSON.@json.js`
import { a } from './a.js'
const SAMPLE_JSON = {
a,
b: 2, // with some more comment
c: 'a'.repeat(20) // allow simple compute
}
export { SAMPLE_JSON }

// file: `a.js`
const a = 1
export { a }

After the loader, output should be like:

var SAMPLE_JSON = JSON.parse('{"a":1,"b":2,"c":"aaaaaaaaaaaaaaaaaaaa"}')
export { SAMPLE_JSON }

The webpack config:

{
  test: /\.@json\.js$/, // also remember to add exclude from normal js loader
  use: { loader: 'json-compact-loader') }
}

The configurable option:

{
  babelConfig: null, // default to only '@babel/plugin-transform-modules-commonjs'
  useConst: false // default to output ES5 code with import/export
}

There's a test setup can be used as example, and the source code is rather simple, too.

About

Replace big named export value to 'JSON.parse(...)'

License:MIT License


Languages

Language:JavaScript 100.0%