Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 11 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,20 @@ npm install --save-dev webpack-config-plugin

```js
// webpack.config.js
var path = require("path")
var ConfigPlugin = require("webpack-config-plugin")
var path = require('path');
var ConfigPlugin = require('webpack-config-plugin');

module.exports = {
// [...]
plugins: [
// [...]
new ConfigPlugin({
// Configuration directory
dir: path.join(__dirname, "config")

// Configuration directory (required)
dir: path.join(__dirname, 'config'),

// Filter expression(s) (optional)
filter: [ '-secret.property' ]
})
]
}
Expand All @@ -31,3 +35,6 @@ module.exports = {
When the plugin has been configured it enables a faux-module `config` which
is a merge between a default configuration, an environment-specific
configuration, and a local configuration.

Please see [json-property-filter](https://www.npmjs.com/package/json-property-filter)
for documentation of filter expressions.
18 changes: 14 additions & 4 deletions lib/config-loader.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,14 @@
module.exports = function() {
var config = JSON.parse(this.query.slice(1))
return "module.exports = " + JSON.stringify(config)
}
const { JsonPropertyFilter } = require('json-property-filter');

module.exports = function () {
const { config, filter = [] } = JSON.parse(this.query.slice(1));

if (Array.isArray(filter) && filter.length > 0) {
const propertyFilter = new JsonPropertyFilter(filter);
const filteredOutput = propertyFilter.apply(config);

return `module.exports = ${JSON.stringify(filteredOutput)}`;
}

return `module.exports = ${JSON.stringify(config)}`;
};
163 changes: 95 additions & 68 deletions lib/config-plugin.js
Original file line number Diff line number Diff line change
@@ -1,76 +1,103 @@
var _ = require("lodash")
var path = require("path")

// Load configuration file
function loadFile(dir, filename) {
if (filename == null) return {}
filename = path.join(dir, filename)
try {
return require(filename)
} catch(e) {
return {}
const assert = require('assert');
const path = require('path');
const merge = require('lodash/merge');

class Config {

// Load configuration file.
// Fails gracefully by returning an empty object.
static loadConfigFile(dir, filename) {
if (!filename) {
return {};
}

try {
const pathname = path.resolve(dir, filename);

return require(pathname);
} catch (error) {
return {};
}
}
}

module.exports = Config
function Config(options) {
this.options = options
this._config = null
constructor(options = {}) {
assert(typeof options.dir === 'string', 'WebpackConfigPlugin: "options.dir" must be provided');
assert(!options.filter || Array.isArray(options.filter), 'WebpackConfigPlugin: "options.filter" must be an array. See "json-property-filter" package for more details');

this.options = options;
this.config = null;

if (this.options.environment == null) {
this.options.environment = process.env.NODE_ENV || "development"
if (!this.options.environment) {
this.options.environment = process.env.NODE_ENV || 'development';
}
}
}

Config.prototype.getConfig = function () {
if (!this._config) {
this._config = _.merge({},
loadFile(this.options.dir, "default"),
loadFile(this.options.dir, this.options.environment),
loadFile(this.options.dir, "local")
)
getConfig() {
if (!this.config) {
const { dir, environment } = this.options;

this.config = merge(
{},
Config.loadConfigFile(dir, 'default'),
Config.loadConfigFile(dir, environment),
Config.loadConfigFile(dir, 'local')
);
}

return this.config;
}
return this._config
}

Config.prototype.apply = function(compiler) {
// Build the configuration object
var config = this.getConfig()

compiler.plugin('compilation', function(compilation) {
// Setup a resolver to faux-resolve a request for "config"
compilation.resolvers.normal.plugin("module", function(request, next) {
if (request.request !== "config") {
// This plugin only resolves for the explicit module "config"
return next()
}

return next(null, {
// This path is not actually used but must be set to a real file
path: "package.json",
resolved: true
})
})
})

// Setup a module-factory to direct the flow to the loader (
// which outputs the configuration JSON)
compiler.plugin("normal-module-factory", function(nmf) {
nmf.plugin("after-resolve", function(data, next) {
if (data.rawRequest !== "config") {
// This plugin only resolves for the explicit module "config"
return next(null, data)
}

// console.log(data)
// NOTE: Parameters are passed via query string to the loader
// at `this.query`
data.loaders = [
path.join(__dirname, "./config-loader.js") + "?" +
JSON.stringify(config)
]

return next(null, data)
})
})
apply(compiler) {

// Build the configuration object
const config = this.getConfig();

compiler.plugin('compilation', compilation => {

// Setup a resolver to faux-resolve a request for "config"
compilation.resolvers.normal.plugin('module', (request, next) => {
if (request.request !== 'config') {

// This plugin only resolves for the explicit module "config"
return next();
}

return next(null, {

// This path is not actually used but must be set to a real file
path: 'package.json',
resolved: true
});
});
});

// Setup a module-factory to direct the flow to the loader (
// which outputs the configuration JSON)
compiler.plugin('normal-module-factory', factory => {
factory.plugin('after-resolve', (data, next) => {
if (data.rawRequest !== 'config') {

// This plugin only resolves for the explicit module "config"
return next(null, data);
}

const { filter } = this.options;
const loaderPathname = path.resolve(__dirname, 'config-loader.js');
const loaderQuery = {
config,
filter
};

// NOTE: Parameters are passed via query string to the loader
// at `this.query`
data.loaders = [
`${loaderPathname}?${JSON.stringify(loaderQuery)}`
];

return next(null, data);
});
});
}
}

module.exports = Config;
18 changes: 14 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"name": "webpack-config-plugin",
"version": "1.0.0",
"version": "1.1.0",
"description": "Configuration plugin (in the style of node-config) for webpack.",
"main": "lib/config-plugin.js",
"peerDependencies": {
"webpack": ">=1.4.0"
"engines": {
"node": ">=6"
},
"repository": {
"type": "git",
Expand All @@ -20,12 +20,22 @@
"email": "leckey.ryan@gmail.com",
"url": "https://github.com/mehcode"
},
"contributors": [
{
"name": "J. Snaras",
"email": "j@snaras.com"
}
],
"license": "MIT",
"bugs": {
"url": "https://github.com/mehcode/webpack-config-plugin/issues"
},
"homepage": "https://github.com/mehcode/webpack-config-plugin",
"dependencies": {
"lodash": "^3.10.1"
"json-property-filter": "^1.3.1",
"lodash": "^4.17.4"
},
"peerDependencies": {
"webpack": ">=1.4.0"
}
}