If every client needs access to a shared chunk of data, and that data
can be known at build time, a simple option is to bake that data into
clientside build with tojson-loader
.
- Having shared, static data preloaded in the client can improve performance/UX & reduce complexity.
- Use whatever tools you need to generate the data on the serverside, no need to worry about shipping or shimming them on the client.
- Reduce client-side processing load. Perform expensive calulations only once, on the server, at build-time.
- Designed so tojson scripts can be transparently universal. Will run dynamic version on server & load static version on client.
Particularly useful for loading configuration and/or mock data into the client.
- Only supports JSON data types i.e. JSON can't natively serialise
Function
orDate
objects.
// webpack.config.js
module.exports = {
...
module: {
loaders: [
{
// Use *.json.js extension to bake exported JS data into JSON
test: /\.json\.js/,
loader: 'tojson'
}
...
]
}
}
// data.json.js
// can use serverside-only dependencies
var fs = require('fs')
var readme = fs.readFileSync(__dirname + '/../../Readme.md', 'utf8')
readme = readme.split('\n')[0] // (just grab header for demo)
// any other dependencies that are only used in here won't be included in bundle
var tape = require('tape') // some random dependency
// whatever the value of module.exports is will be serialised to JSON
module.exports = {
readme: readme,
tape: tape, // tape happens to be a function so it won't serialise.
random: Math.random(), // will be fixed to whatever value is generated at compile-time
}
// data.json.js
var fs = require('fs')
// If module exports a function, it becomes asynchronous.
// After all hard work it should send results to resolve function
module.exports = function (resolve) {
fs.readFile(__dirname + '/../../Readme.md', 'utf8', function (err, readme) {
readme = readme.split('\n')[0] // (just grab header for demo)
// any other dependencies that are only used in here won't be included in bundle
var tape = require('tape') // some random dependency
// Resulting object should be sent to resolve function
resolve({
readme: readme,
tape: tape, // tape happens to be a function so it won't serialise.
random: Math.random(), // will be fixed to whatever value is generated at compile-time
})
})
}
// index.js
console.log(require('./data.json.js'))
The transformed output after being built by webpack is below.
Note:
- No dependencies on any of the modules (
fs
,tape
) used. - Result of
fs.readFileSync
is baked into the output. random
key will always be the same value until next build.tape
key doesn't exist because JSON can't serialise functions.
...
/******/ ([
/* 0 */
/***/ function(module, exports, __webpack_require__) {
console.log(__webpack_require__(1))
/***/ },
/* 1 */
/***/ function(module, exports) {
module.exports = {"readme":"# tojson-loader","random":0.5418716457206756}
/***/ }
/******/ ]);
ISC