Thursday, May 23, 2024
 Popular · Latest · Hot · Upcoming
153
rated 0 times [  159] [ 6]  / answers: 1 / hits: 24632  / 7 Years ago, sun, may 28, 2017, 12:00:00

I'd like to assemble a manifest.json file, as used by Chrome extensions, in a smarter, programmatic sort of way. I'm using npm for my dependency resolution, and its package.json includes some shared fields with the manifest.json file, including name, description, and version.



Is there a way to define something like a partial manifest.json file which includes all the Chrome-specific stuff, but fill in shared values where appropriate? I've found that this is pretty straightforward in Gulp:



var gulp = require('gulp');
var fs = require('fs');
var jeditor = require('gulp-json-editor');

gulp.task('manifest', function() {
var pkg = JSON.parse(fs.readFileSync('./package.json'));
gulp.src('./manifest.json')
.pipe(jeditor({
'name': pkg.name,
'description': pkg.description,
'version': pkg.version,
'author': pkg.author,
'homepage_url': pkg.homepage,
}))
.pipe(gulp.dest(./dist));
});


Even if there's some npm package out there designed for this purpose, can someone explain to me how something like this might be done generally? I know Webpack 2 has a built-in json loader, but I'm not clear how it would be used in a case like this.


More From » npm

 Answers
95

Credit to Sean Larkin from the Webpack project for reaching out to me and helping me figure out how to get this done. I needed to create a custom loader to handle reading the existing manifest.json and adding my fields of interest to it.



// File: src/manifest-loader.js

const fs = require('fs');

// A loader to transform a partial manifest.json file into a complete
// manifest.json file by adding entries from an NPM package.json.
module.exports = function(source) {
const pkg = JSON.parse(fs.readFileSync('./package.json'));
const merged = Object.assign({}, JSON.parse(source), {
'name': pkg.name,
'description': pkg.description,
'version': pkg.version,
'author': pkg.author,
'homepage_url': pkg.homepage,
});
const mergedJson = JSON.stringify(merged);
// In Webpack, loaders ultimately produce JavaScript. In order to produce
// another file type (like JSON), it needs to be emitted separately.
this.emitFile('manifest.json', mergedJson);
// Return the processed JSON to be used by the next item in the loader chain.
return mergedJson;
};


Then configure webpack to use my custom manifest-loader.



// File: webpack.config.js

const path = require('path');

module.exports = {
// Tell Webpack where to find our custom loader (in the src directory).
resolveLoader: {
modules: [path.resolve(__dirname, src), node_modules]
},

// The path to the incomplete manifest.json file.
entry: ./manifest.json,
output: {
// Where the newly built manifest.json will go.
path: path.resolve(__dirname, 'dist'),
// This file probably won't actually be used by anything.
filename: manifest.js,
},

module: {
rules: [
{
// Only apply these loaders to manifest.json.
test: /manifest.json$/,
// Loaders are applied in reverse order.
use: [
// Second: JSON -> JS
json-loader,
// First: partial manifest.json -> complete manifest.json
manifest-loader,
]
}
]
}
};


The result, when running Webpack, is a dist/ directory containing manifest.js and manifest.json, with manifest.json containing everything from the original, top-level manifest.json plus the additional info from package.json. The extra manifest.js is a script that exposes the contents of manifest.json to any other JavaScript in the project that wants it. This is probably not too useful, but a Chrome extension might conceivably want to require this in a script somewhere to expose some of this information in a friendly way.


[#57635] Thursday, May 25, 2017, 7 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
destiney

Total Points: 175
Total Questions: 96
Total Answers: 93

Location: Zambia
Member since Sat, Nov 6, 2021
3 Years ago
;