Replace big named export value to 'JSON.parse(...)'
- 📁 source/
- source code, in output package will be:
json-compact-loader/library
- source code, in output package will be:
- 📁 test/
- basic test with webpack, run with
npm run test-webpack
ornpm run test-webpack-watch
- basic test with webpack, run with
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+.
Sad, but there's some limit to what the code can do:
- the file naming should be
[email protected]
, and theNAME_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 withexport { NAME_OF_JSON }
- data generation with code is supported,
but only further
import
of.js/json
is allowed, norequire
for now, this is because webpack need to know the related file, butrequire
is hard to parse correctly
That's it,
note the [email protected]
suffix is recommended, but not required,
change it to something else if needed.
With source like:
// file: `[email protected]`
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.