How do I build a JSON file with webpack?
我想以一种"更智能"的程序化方式来组装Chrome扩展程序使用的
是否可以定义部分
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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")); }); |
即使有一些为此目的而设计的npm软件包,也有人可以向我解释一般如何做吗? 我知道Webpack 2有一个内置的json加载器,但是我不清楚在这种情况下如何使用它。
实际上,有一个比@ user108471提供的解决方案更优雅的解决方案(尽管它受其启发),那就是使用
它有两个优点:
-
它不会生成多余的
manifest.js -bundle(@bronson的解决方案也可以解决此问题) -
您不需要在其他
.js 文件中require manifest.json (在我看来在语义上是倒退的)
最小的设置可能是这样的:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | // 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) } }]) ] } |
感谢Webpack项目中的Sean Larkin与我联系并帮助我弄清楚如何完成此工作。我需要创建一个自定义加载器来处理读取现有的
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | // 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; }; |
然后将webpack配置为使用我的自定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | // 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", ] } ] } }; |
运行Webpack时,结果是包含
我在下面的Webpack 4中的解决方案。这是使用Webpack加载程序生成json文件的通用解决方案,但它也适用于manifest.json文件。
webpack.config.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 | 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"), ] }; |
app / main.js
1 2 3 | const manifest = require('./manifest.js'); // Other parts of app … |
app / manifest.js
1 2 3 4 5 6 7 8 9 10 | 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); |
package.json依赖项
1 2 3 4 5 | { "extract-text-webpack-plugin":"4.0.0-beta.0", "file-loader":"1.1.11", "webpack":"4.12.0", } |
我使用了足够多的脚本,因此在NPM上发布了该脚本的某种修改版本:https://github.com/bronson/manifest-package-loader
希望它像
巧合的是,就在今天早上,我遇到了chem-loader,它也可能起作用:https://github.com/mrmisterman/chem-loader
试试这个包,您可以读取您的json文件,然后在自定义它之后构建新的json。
https://github.com/webpack-contrib/json-loader