Skip to content
This repository has been archived by the owner on Nov 16, 2023. It is now read-only.

Commit

Permalink
add support for dynamic filenames
Browse files Browse the repository at this point in the history
Add support for custom filename template for worker scripts.
  • Loading branch information
jimmydief committed Nov 21, 2019
1 parent 1d1473d commit ac12a4a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 14 deletions.
4 changes: 3 additions & 1 deletion README.md
Expand Up @@ -48,9 +48,11 @@ Options can be passed in to `MonacoWebpackPlugin`. They can be used to generate

* `output` (`string`) - custom output path for worker scripts, relative to the main webpack `output.path`.
* default value: `''`.
* `filename` (`string`) - custom filename template for worker scripts, respects the same options as [loader-utils' interpolateName](https://github.com/webpack/loader-utils#interpolatename). Useful for adding content-based hashes so that files can be served with long-lived caching headers.
* default value: `'[name].worker.js'`.
* `languages` (`string[]`) - include only a subset of the languages supported.
* default value: `['apex', 'azcli', 'bat', 'clojure', 'coffee', 'cpp', 'csharp', 'csp', 'css', 'dockerfile', 'fsharp', 'go', 'handlebars', 'html', 'ini', 'java', 'javascript', 'json', 'less', 'lua', 'markdown', 'msdax', 'mysql', 'objective', 'perl', 'pgsql', 'php', 'postiats', 'powerquery', 'powershell', 'pug', 'python', 'r', 'razor', 'redis', 'redshift', 'ruby', 'rust', 'sb', 'scheme', 'scss', 'shell', 'solidity', 'sql', 'st', 'swift', 'typescript', 'vb', 'xml', 'yaml']`.

Some languages share the same web worker. If one of the following languages is included, you must also include the language responsible for instantiating their shared worker:

| Language | Instantiator |
Expand Down
6 changes: 6 additions & 0 deletions index.d.ts
Expand Up @@ -17,6 +17,12 @@ interface IMonacoEditorWebpackPluginOpts {
* Use e.g. '!contextmenu' to exclude a certain feature.
*/
features?: string[];

/**
* Specify a filename template to use for generated files.
* Use e.g. '[name].worker.[contenthash].js' to include content-based hashes.
*/
filename?: string;
}

declare class MonacoEditorWebpackPlugin extends Plugin {
Expand Down
33 changes: 24 additions & 9 deletions index.js
@@ -1,5 +1,8 @@
const path = require('path');
const webpack = require('webpack');
const loaderUtils = require('loader-utils');
const fs = require('fs');

const AddWorkerEntryPointPlugin = require('./plugins/AddWorkerEntryPointPlugin');
const INCLUDE_LOADER_PATH = require.resolve('./loaders/include');

Expand All @@ -9,18 +12,29 @@ const EDITOR_MODULE = {
worker: {
id: 'vs/editor/editor',
entry: 'vs/editor/editor.worker',
output: 'editor.worker.js',
fallback: undefined
},
alias: undefined,
};
const LANGUAGES = require('./languages');
const FEATURES = require('./features');

/**
* Return a resolved path for a given Monaco file.
*/
function resolveMonacoPath(filePath) {
return require.resolve(path.join('monaco-editor/esm', filePath));
}

/**
* Return the interpolated final filename for a worker, respecting the file name template.
*/
function getWorkerFilename(filename, entry) {
return loaderUtils.interpolateName({resourcePath: entry}, filename, {
content: fs.readFileSync(resolveMonacoPath(entry))
});
}

const languagesById = fromPairs(
flatMap(toPairs(LANGUAGES), ([id, language]) =>
[id].concat(language.alias || []).map((label) => [label, mixin({ label }, language)])
Expand Down Expand Up @@ -57,19 +71,20 @@ class MonacoWebpackPlugin {
this.options = {
languages: languages.map((id) => languagesById[id]).filter(Boolean),
features: features.map(id => featuresById[id]).filter(Boolean),
filename: options.filename || "[name].worker.js",
output,
};
}

apply(compiler) {
const { languages, features, output } = this.options;
const { languages, features, filename, output } = this.options;
const publicPath = getPublicPath(compiler);
const modules = [EDITOR_MODULE].concat(languages).concat(features);
const workers = modules.map(
({ label, alias, worker }) => worker && (mixin({ label, alias }, worker))
).filter(Boolean);
const rules = createLoaderRules(languages, features, workers, output, publicPath);
const plugins = createPlugins(workers, output);
const rules = createLoaderRules(languages, features, workers, filename, output, publicPath);
const plugins = createPlugins(workers, filename, output);
addCompilerRules(compiler, rules);
addCompilerPlugins(compiler, plugins);
}
Expand All @@ -89,11 +104,11 @@ function getPublicPath(compiler) {
return compiler.options.output && compiler.options.output.publicPath || '';
}

function createLoaderRules(languages, features, workers, outputPath, publicPath) {
function createLoaderRules(languages, features, workers, filename, outputPath, publicPath) {
if (!languages.length && !features.length) { return []; }
const languagePaths = flatArr(languages.map(({ entry }) => entry).filter(Boolean));
const featurePaths = flatArr(features.map(({ entry }) => entry).filter(Boolean));
const workerPaths = fromPairs(workers.map(({ label, output }) => [label, path.join(outputPath, output)]));
const workerPaths = fromPairs(workers.map(({ label, entry }) => [label, getWorkerFilename(filename, entry)]));
if (workerPaths['typescript']) {
// javascript shares the same worker
workerPaths['javascript'] = workerPaths['typescript'];
Expand Down Expand Up @@ -140,14 +155,14 @@ function createLoaderRules(languages, features, workers, outputPath, publicPath)
];
}

function createPlugins(workers, outputPath) {
function createPlugins(workers, filename, outputPath) {
return (
[]
.concat(uniqBy(workers, ({ id }) => id).map(({ id, entry, output }) =>
.concat(uniqBy(workers, ({ id }) => id).map(({ id, entry }) =>
new AddWorkerEntryPointPlugin({
id,
entry: resolveMonacoPath(entry),
filename: path.join(outputPath, output),
filename: getWorkerFilename(filename, entry),
plugins: [
new webpack.optimize.LimitChunkCountPlugin({ maxChunks: 1 }),
],
Expand Down
4 changes: 0 additions & 4 deletions languages.js
Expand Up @@ -47,7 +47,6 @@ module.exports = {
worker: {
id: 'vs/language/css/cssWorker',
entry: 'vs/language/css/css.worker',
output: 'css.worker.js',
fallback: 'vs/language/css/cssWorker',
},
alias: undefined,
Expand Down Expand Up @@ -80,7 +79,6 @@ module.exports = {
worker: {
id: 'vs/language/html/htmlWorker',
entry: 'vs/language/html/html.worker',
output: 'html.worker.js',
fallback: 'vs/language/html/htmlWorker',
},
alias: undefined,
Expand All @@ -105,7 +103,6 @@ module.exports = {
worker: {
id: 'vs/language/json/jsonWorker',
entry: 'vs/language/json/json.worker',
output: 'json.worker.js',
fallback: 'vs/language/json/jsonWorker',
},
alias: undefined,
Expand Down Expand Up @@ -258,7 +255,6 @@ module.exports = {
worker: {
id: 'vs/language/typescript/tsWorker',
entry: 'vs/language/typescript/ts.worker',
output: 'typescript.worker.js',
fallback: 'vs/language/typescript/tsWorker',
},
alias: undefined,
Expand Down

0 comments on commit ac12a4a

Please sign in to comment.