Skip to content

Commit

Permalink
Add ability to pass in locals as a function
Browse files Browse the repository at this point in the history
  • Loading branch information
jahredhope committed Oct 23, 2018
1 parent b159e1b commit 79eb95c
Show file tree
Hide file tree
Showing 8 changed files with 97 additions and 18 deletions.
28 changes: 24 additions & 4 deletions README.md
Expand Up @@ -101,14 +101,34 @@ Note that this will still be executed for each entry in your `paths` array in yo
// The path currently being rendered:
locals.path;

// An object containing all assets:
locals.assets;

// Advanced: Webpack's stats object:
locals.webpackStats;
```

Any additional locals provided in your config are also available.
## Custom locals

To customise the locals provided to your render function you can use the `locals` option.
A function passed to this option will be called before each render.
The result will be used when rendering.

```js
const template = ejs.compile(templateSource);

module.exports = {

...

plugins: [
new StaticSiteGeneratorPlugin({
locals: ({ path, webpackStats }) => {
template,
path,
webpackStats
}
})
]
}
```

## Crawl mode

Expand Down
41 changes: 29 additions & 12 deletions index.js
Expand Up @@ -5,16 +5,20 @@ var cheerio = require('cheerio');
var url = require('url');
var Promise = require('bluebird');

function defaultLocalsTransform(locals) {
return locals;
}

function StaticSiteGeneratorWebpackPlugin(options) {
if (arguments.length > 1) {
options = legacyArgsToOptions.apply(null, arguments);
}

options = options || {};
options = normalizeOptions(options);

this.entry = options.entry;
this.paths = Array.isArray(options.paths) ? options.paths : [options.paths || '/'];
this.locals = options.locals;
this.locals = options.locals || defaultLocalsTransform;
this.globals = options.globals;
this.crawl = Boolean(options.crawl);
}
Expand Down Expand Up @@ -59,19 +63,13 @@ StaticSiteGeneratorWebpackPlugin.prototype.apply = function(compiler) {
});
};

function renderPaths(crawl, userLocals, paths, render, assets, webpackStats, compilation) {
function renderPaths(crawl, transformLocals, paths, render, assets, webpackStats, compilation) {
var renderPromises = paths.map(function(outputPath) {
var locals = {
var locals = transformLocals({
path: outputPath,
assets: assets,
webpackStats: webpackStats
};

for (var prop in userLocals) {
if (userLocals.hasOwnProperty(prop)) {
locals[prop] = userLocals[prop];
}
}
});

var renderPromise = render.length < 2 ?
Promise.resolve(render(locals)) :
Expand All @@ -97,7 +95,7 @@ function renderPaths(crawl, userLocals, paths, render, assets, webpackStats, com
path: key
});

return renderPaths(crawl, userLocals, relativePaths, render, assets, webpackStats, compilation);
return renderPaths(crawl, transformLocals, relativePaths, render, assets, webpackStats, compilation);
}
});

Expand Down Expand Up @@ -219,6 +217,25 @@ function relativePathsFromHtml(options) {
});
}

function normalizeOptions(legacyOptions) {
var options = Object.assign({}, legacyOptions);

if (options.locals && typeof options.locals !== 'function') {
var userLocals = options.locals;
options.locals = (defaultLocals) => {
return Object.assign(
{
webpackStats: defaultLocals.webpackStats,
path: defaultLocals.path,
assets: defaultLocals.assets
},
userLocals
);
};
}
return options;
}

function legacyArgsToOptions(entry, paths, locals, globals) {
return {
entry: entry,
Expand Down
8 changes: 8 additions & 0 deletions test/__snapshots__/index.spec.js.snap
Expand Up @@ -436,3 +436,11 @@ Object {
"index.js": "CONTENTS IGNORED IN SNAPSHOT TEST",
}
`;
exports[`Success cases transform-locals should generate the expected files 1`] = `
Object {
"bar.js": "CONTENTS IGNORED IN SNAPSHOT TEST",
"index.html": "<div>/foo/bar.js<br />/foo/main.js</div>",
"main.js": "CONTENTS IGNORED IN SNAPSHOT TEST",
}
`;
2 changes: 1 addition & 1 deletion test/index.spec.js
Expand Up @@ -6,7 +6,7 @@ const webpack = promisify(require('webpack'));
const rimrafAsync = promisify(require('rimraf'));
const getSubDirsSync = require('./utils/get-sub-dirs-sync');
const dirContentsToObject = require('./utils/dir-contents-to-object');
const directoryContains = require('./utils/directory-contains');
const directoryContains = require('./utils/directory-contains-html');

const successCases = getSubDirsSync(__dirname + '/success-cases');
const errorCases = getSubDirsSync(__dirname + '/error-cases');
Expand Down
1 change: 1 addition & 0 deletions test/success-cases/transform-locals/bar.js
@@ -0,0 +1 @@
module.exports = 'Foo';
3 changes: 3 additions & 0 deletions test/success-cases/transform-locals/index.js
@@ -0,0 +1,3 @@
module.exports = function(locals) {
return '<div>' + locals.chunks.join('<br />') + '</div>';
};
30 changes: 30 additions & 0 deletions test/success-cases/transform-locals/webpack.config.js
@@ -0,0 +1,30 @@
var StaticSiteGeneratorPlugin = require('../../../');
var ejs = require('ejs');
var fs = require('fs');

var paths = ['/', '/foo', '/foo/bar'];

module.exports = {
entry: {
bar: __dirname + '/bar.js',
main: __dirname + '/index.js'
},

output: {
filename: '[name].js',
path: __dirname + '/actual-output',
publicPath: '/foo/',
libraryTarget: 'umd'
},

plugins: [
new StaticSiteGeneratorPlugin({
entry: 'main',
locals: ({ path, webpackStats }) => ({
chunks: Object.keys(webpackStats.compilation.assets).map(
file => `${webpackStats.compilation.outputOptions.publicPath}${file}`
)
})
})
]
};
Expand Up @@ -21,7 +21,7 @@ module.exports = function(referenceDir, targetDir, done) {
});
};

glob('**/*', { cwd: referenceDir, nodir: true }, function(err, files) {
glob('**/*.html', { cwd: referenceDir, nodir: true }, function(err, files) {
if (err) {
return done(err);
}
Expand Down

0 comments on commit 79eb95c

Please sign in to comment.