Je voudrais assembler un fichier manifest.json
, Tel qu'utilisé par Chrome, d'une manière programmatique "plus intelligente". J'utilise npm pour ma résolution de dépendance , et son package.json
inclut des champs partagés avec le fichier manifest.json
, y compris "nom", "description" et "version".
Existe-t-il un moyen de définir quelque chose comme un fichier partiel manifest.json
Qui inclut tous les éléments spécifiques à Chrome, mais remplissez les valeurs partagées le cas échéant? J'ai trouvé que c'est assez simple dans 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"));
});
Même s'il existe un package npm conçu à cet effet, quelqu'un peut-il m'expliquer comment une telle chose pourrait être faite en général? Je sais que Webpack 2 a un chargeur json intégré, mais je ne sais pas comment il serait utilisé dans un cas comme celui-ci.
Nous remercions Sean Larkin du projet Webpack de m'avoir contacté et de m'avoir aidé à comprendre comment y parvenir. Je devais créer un chargeur personnalisé pour gérer la lecture du manifest.json
Existant et y ajouter mes champs d'intérêt.
// 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;
};
Ensuite, configurez webpack pour utiliser mon manifest-loader
Personnalisé.
// 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",
]
}
]
}
};
Le résultat, lors de l'exécution de Webpack, est un répertoire dist/
Contenant manifest.js
Et manifest.json
, Avec manifest.json
Contenant tout à partir du niveau supérieur d'origine manifest.json
Plus les informations supplémentaires de package.json
. Le supplément manifest.js
Est un script qui expose le contenu de manifest.json
À tout autre code JavaScript du projet qui le souhaite. Ce n'est probablement pas trop utile, mais une extension Chrome pourrait éventuellement vouloir require
ceci dans un script quelque part pour exposer certaines de ces informations de manière conviviale.
Il existe en fait une solution plus élégante que celle de @ user108471 (bien qu'elle s'en inspire), et c'est d'utiliser le copy-webpack-plugin
. Avec sa capacité transform
, vous pouvez ajouter les valeurs souhaitées à la manifest.json
à la volée avant de le copier vers sa destination.
Il présente deux avantages:
manifest.js
- bundle ( @ bronson's solution corrige également cela)require
le manifest.json
dans d'autres .js
- fichier (qui me semblerait sémantique à l'envers)Une configuration minimale pourrait être la suivante:
webpack.config.js
// you can just require .json, saves the 'fs'-hassle
let package = require('./package.json');
function modify(buffer) {
// copy-webpack-plugin passes a buffer
var manifest = JSON.parse(buffer.toString());
// make any modifications you like, such as
manifest.version = package.version;
// pretty print to JSON with two spaces
manifest_JSON = JSON.stringify(manifest, null, 2);
return manifest_JSON;
}
module.exports = {
// ...
plugins: [
new CopyWebpackPlugin([
{
from: "./src/manifest.json",
to: "./dist/manifest.json",
transform (content, path) {
return modify(content)
}
}])
]
}
Ma solution dans Webpack 4 ci-dessous. C'est une solution générique pour générer des fichiers json à l'aide des chargeurs Webpack, mais cela fonctionne également pour les fichiers manifest.json.
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const resolve = require("path").resolve;
module.exports = {
entry: {
entry: resolve(__dirname, "app/main.js"),
},
module: {
rules: [
{
test: /manifest\.js$/,
use: ExtractTextPlugin.extract({
use: [] // Empty array on purpose.
})
}
],
{
test: /\.png$/,
use: [{
loader: "file-loader",
options: {
context: resolve(__dirname, "app"),
name: "[path][name].[ext]",
publicPath: "/",
}
}]
}
},
output: {
filename: "[name].js",
path: resolve(__dirname, 'dist'),
},
plugins: [
new webpack.EnvironmentPlugin(["npm_package_version"]), // automagically populated by webpack, available as process.env.npm_package_version in loaded files.
new ExtractTextPlugin("manifest.json"),
]
};
const manifest = require('./manifest.js');
// Other parts of app …
const icon = require('./icon.png');
const manifestData = {
icon: {"128": icon}, // icon.png will be in the emitted files, yay!
version: process.env.npm_package_version, // See webpack.config.js plugins
// other manifest data …
};
// Whatever string you output here will be emitted as manifest.json:
module.exports = JSON.stringify(manifestData, null, 2);
{
"extract-text-webpack-plugin": "4.0.0-beta.0",
"file-loader": "1.1.11",
"webpack": "4.12.0",
}
Si vous utilisez webpack 4, c'est assez simple. Nous n'avons pas besoin de spécifier de chargeurs json explicites
Remarque: je regroupe simplement tout dans un seul fichier html ici, mais vous avez l'idée qu'il n'y a pas de chargeur json dans le fichier webpack.config.js
webpack.config.js
const HtmlWebPackPlugin = require("html-webpack-plugin");
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
module.exports = {
module: {
rules: [
{
test: /\.js$/,
exclude: [/node_modules/],
use: [{
loader: 'babel-loader'
}],
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
},
{
test: /\.ico$/,
use: ["file-loader"]
},
{
test: /\.html$/,
use: [
{
loader: "html-loader",
options: { minimize: true }
}
]
}
],
},
plugins: [
new HtmlWebPackPlugin({
template: "./src/index.html",
filename: "./index.html",
inlineSource: '.(js|css)$'
}),
new HtmlWebpackInlineSourcePlugin(),
],
devServer: {
compress: true,
disableHostCheck: true,
}
}
Dans mon app.js, j'utilise simplement
import data from './data/data.json'
J'utilisais suffisamment votre script pour en publier une version quelque peu modifiée sur NPM: https://github.com/bronson/manifest-package-loader
J'espère que c'est aussi simple que yarn add -D manifest-package-loader
et mettre à jour votre webpack.config.js.
Par coïncidence, ce matin, j'ai rencontré chem-loader, ce qui pourrait également fonctionner: https://github.com/mrmisterman/chem-loader