chunks-2-json-webpack-plugin
Advanced tools
Comparing version 0.0.3 to 1.0.0
108
index.js
@@ -6,5 +6,18 @@ const fs = require('fs'); | ||
const defaultOptions = { | ||
// ignore files emitted by HMR by default | ||
excludeFile: /\.hot-update\.js$/, | ||
// group chunks by extension | ||
chunkGroupName: filename => /\.([a-z0-9]+(\.map)?)(\?.*)?$/.exec(filename)[1], | ||
outputDir: process.cwd(), | ||
filename: 'build-manifest.json', | ||
// generate contents to save to manifest file | ||
objectToString: result => JSON.stringify(result), | ||
publicPath: '' | ||
}; | ||
class Chunks2JsonWebpackPlugin { | ||
constructor(options) { | ||
this.options = options; | ||
// overwrite default options | ||
this.options = Object.assign({}, defaultOptions, options); | ||
this.result = {}; | ||
@@ -14,16 +27,16 @@ } | ||
compiler.hooks.emit.tap(pluginName, compilation => { | ||
compilation.chunks.forEach((chunk) => { | ||
this.result = {}; | ||
compilation.chunks.forEach(chunk => { | ||
if (this.result[chunk.name] === undefined) { | ||
this.result[chunk.name] = {}; | ||
} | ||
chunk.files.forEach((filename) => { | ||
if (filename.endsWith('css')) { | ||
this.result[chunk.name].css = `/${filename}`; | ||
} else if (filename.endsWith('js')) { | ||
this.result[chunk.name].js = `/${filename}`; | ||
} else if (filename.endsWith('js.map')) { | ||
this.result[chunk.name].jsMap = `/${filename}`; | ||
} else if (filename.endsWith('css.map')) { | ||
this.result[chunk.name].cssMap = `/${filename}`; | ||
chunk.files.forEach(filename => { | ||
if (this._excludeChunk(this.options.excludeFile, filename, chunk) === true) { | ||
return; | ||
} | ||
const ext = this.options.chunkGroupName(filename, chunk); | ||
if (this.result[chunk.name][ext] === undefined) { | ||
this.result[chunk.name][ext] = []; | ||
} | ||
this.result[chunk.name][ext].push(`${this.options.publicPath}${filename}`); | ||
}); | ||
@@ -35,14 +48,18 @@ }); | ||
saveJson() { | ||
const projectRoot = process.cwd(); | ||
let pathStep = projectRoot; | ||
this.options.outputDir.replace(projectRoot, '').split('/').forEach((folder) => { | ||
pathStep = path.join(pathStep, folder); | ||
try { | ||
fs.mkdirSync(pathStep); | ||
} catch (e) { | ||
// we don't care if it already exists, just continue... | ||
} | ||
}); | ||
const file = path.join(process.cwd(), this.options.outputDir, this.options.filename); | ||
const blob = JSON.stringify(this.result, undefined, 2); | ||
// try to create outputDir folder if it is within project root | ||
if (this._shouldFolderBeCreated(this.options.outputDir) === true) { | ||
let pathStep = process.cwd(); | ||
// remove relative prefix | ||
const normalizedOutputPath = this._normalizeOutputDir(this.options.outputDir); | ||
normalizedOutputPath.split('/').forEach((folder) => { | ||
pathStep = path.join(pathStep, folder); | ||
try { | ||
fs.mkdirSync(pathStep); | ||
} catch (e) { | ||
// we don't care if it already exists, just continue... | ||
} | ||
}); | ||
} | ||
const file = path.resolve(this.options.outputDir, this.options.filename); | ||
const blob = this.options.objectToString(this.result); | ||
try { | ||
@@ -55,4 +72,47 @@ fs.writeFileSync(file, blob, { flag: 'w' }); | ||
} | ||
/** | ||
* We might want to skip some entries | ||
* this function checks users criteria and returns a bool | ||
* @param Function|RegEx excludeCriterium - passed option to skip some entries | ||
*/ | ||
_excludeChunk(excludeCriterium, filename, chunk) { | ||
if (typeof excludeCriterium === 'function') { | ||
return excludeCriterium(filename, chunk); | ||
} | ||
if (excludeCriterium instanceof RegExp) { | ||
return excludeCriterium.test(filename); | ||
} | ||
// if wrong criteria is passed, we're gonan include the file by default | ||
return true; | ||
} | ||
/** | ||
* We need to make sure, that we can actually create the folder. | ||
* We can do so, if the desired output is inside project root | ||
* @param String outputDir - path to output directory | ||
*/ | ||
_shouldFolderBeCreated(outputDir) { | ||
// this returns absolute path | ||
// handle absolute path, that points to project | ||
const isAbsolutePathWithProjectRoot = outputDir.includes(process.cwd()); | ||
// if output is inside the folder, we're all good | ||
const isPathWithinProjectRoot = !outputDir.startsWith('/'); | ||
return isAbsolutePathWithProjectRoot || | ||
isPathWithinProjectRoot || | ||
false; | ||
} | ||
/** | ||
* To create output folder, we need to understand, | ||
* which folders to create. This function normalizes | ||
* relative and absolute path, to output we can then | ||
* work with - e.g.: folder1/folder2/folder3 | ||
* @param String outputDir - path to outpurDirectory | ||
*/ | ||
_normalizeOutputDir(outputDir) { | ||
const removedRelativePrefix = outputDir.replace(/^\.\//, ''); | ||
const removeAbsolutePrefix = removedRelativePrefix.replace(process.cwd(), ''); | ||
return removeAbsolutePrefix; | ||
} | ||
} | ||
module.exports = Chunks2JsonWebpackPlugin; | ||
module.exports = Chunks2JsonWebpackPlugin; |
{ | ||
"name": "chunks-2-json-webpack-plugin", | ||
"version": "0.0.3", | ||
"version": "1.0.0", | ||
"description": "Plugin for webpack 4, that outputs build files to JSON", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
"test": "jest", | ||
"test:coverage": "jest --collectCoverageFrom='./*.js' --coverage --collectCoverageFrom=!./*.config.js && cat ./test/coverage/lcov.info | coveralls" | ||
}, | ||
@@ -26,3 +27,12 @@ "repository": { | ||
}, | ||
"homepage": "https://github.com/homeday-de/Chunks2JsonPlugin#readme" | ||
"homepage": "https://github.com/homeday-de/Chunks2JsonPlugin#readme", | ||
"devDependencies": { | ||
"babel-jest": "24.1.0", | ||
"babel-preset-env": "1.7.0", | ||
"coveralls": "^3.0.2", | ||
"css-loader": "2.1.0", | ||
"jest": "24.1.0", | ||
"mini-css-extract-plugin": "0.5.0", | ||
"webpack": "^4.29.3" | ||
} | ||
} |
@@ -0,3 +1,5 @@ | ||
[![Build Status](https://travis-ci.com/homeday-de/chunks-2-json-webpack-plugin.svg?branch=master)](https://travis-ci.com/homeday-de/chunks-2-json-webpack-plugin) [![Coverage Status](https://coveralls.io/repos/github/homeday-de/chunks-2-json-webpack-plugin/badge.svg?branch=master)](https://coveralls.io/github/homeday-de/chunks-2-json-webpack-plugin?branch=master) | ||
# chunks-2-json-webpack-plugin | ||
Plugin for webpack 4, that outputs build files to JSON | ||
Plugin for webpack 4, that outputs build files to JSON. Without external dependencies. | ||
@@ -18,3 +20,2 @@ ## Instalation | ||
## Usage example | ||
@@ -29,10 +30,13 @@ | ||
const publicPath = '/app/'; | ||
module.exports = { | ||
entry: './path/to/my/entry/file.js', | ||
entry: './src/index.js', | ||
output: { | ||
filename: 'my-first-webpack.bundle.js', | ||
path: path.resolve(__dirname, 'dist') | ||
filename: '[name].[hash].js', | ||
path: path.resolve(__dirname, 'dist'), | ||
publicPath | ||
}, | ||
plugins: [ | ||
new Chunks2JsonPlugin({ outputDir: 'dist/', filename: 'my-app.json' }) | ||
new Chunks2JsonPlugin({ outputDir: 'dist/', publicPath }) | ||
] | ||
@@ -48,9 +52,9 @@ }; | ||
"chunk-vendors": { | ||
"js": "/js/chunk-vendors.fc40696c.js", | ||
"jsMap": "/js/chunk-vendors.fc40696c.js.map" | ||
"js": ["/app/js/chunk-vendors.fc40696c.js"], | ||
"js.map": ["/app/js/chunk-vendors.fc40696c.js.map"] | ||
}, | ||
"app": { | ||
"css": "/css/app.eb829ccc.css", | ||
"js": "/js/app.dd31cdcb.js", | ||
"jsMap": "/js/app.dd31cdcb.js.map" | ||
"css": ["/app/css/app.eb829ccc.css"], | ||
"js": ["/app/js/app.dd31cdcb.js"], | ||
"js.map": ["/app/js/app.dd31cdcb.js.map"] | ||
} | ||
@@ -60,13 +64,22 @@ } | ||
## Options | ||
There are 2 input options available | ||
| Option | Description | Type | Default | Comment | | ||
| ------------- |-------------| -------------| -------------| -------------| | ||
| **excludeFile** | Option to dynamically exclude some of the files | `RegExp` or `Function` with signature `(filename, chunk) => bool` | ` /\.hot-update\.js$/` | Exclude HMR chunks by default (file names ending with `.hot-update.js`). | | ||
| **chunkGroupName** | Option to define your own file chunk grouping. | `Function` with signature `(filename, chunk) => string` | `filename => /\.([a-z0-9]+(\.map)?)(\?.*)?$/.exec(filename)[1]` | Group by file extension (or `ext.map`) by default. For example for filename inside one chunk `dist/app.js` the default grouping will be `js: []` and for `dist/app.js.map` it would be `js.map: []` both inside of `app` key | | ||
| **outputDir** | Output folder name. If the folder does not exist, we'll try to create it. | `String` | `process.cwd()` | Current working directory by default. | | ||
| **filename** | Output file name. | `String` | `build-manifest.json` | | | ||
| **objectToString** | Function to be used to format the output. | `Function` with signature `(result) => string` | `result => JSON.stringify(result)` | By default we output `JSON`, but you can opt in for any other format as well. Just define your output here and adjust `filename` | ||
| **publicPath** | String to prepend to all chunk file names. You probably should set it to the same value as `webpackConfig.output.publicPath`. | `String` | `''` | Empty string by default | | ||
| Option | Description | | ||
| ------------- |-------------| | ||
| outputDir | Folder in which to output the JSON file. If the folder does not exist, we'll try to create it | | ||
| filename | Name of the outputed JSON file | | ||
## Additional Info | ||
To better understand your custom options, you can learn more about chunks [here](https://github.com/webpack/docs/wiki/how-to-write-a-plugin#exploring-assets-chunks-modules-and-dependencies). | ||
## Questions? | ||
Feel free to open an [issue](https://github.com/homeday-de/chunks-2-json-webpack-plugin/issues). | ||
Feel free to open an issue. | ||
## Contribution or feature request? | ||
Please open a [PR](https://github.com/homeday-de/chunks-2-json-webpack-plugin/pulls) or [issue](https://github.com/homeday-de/chunks-2-json-webpack-plugin/issues). |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
19755
41
399
0
81
7
3
1