webpack-util.js 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970
  1. const fs = require('fs');
  2. const babelCore = require('@babel/core');
  3. const WrapperWebpackPlugin = require('wrapper-webpack-plugin');
  4. const entryGlobals = {
  5. 'common': [],
  6. 'injected/content': [],
  7. 'injected/web': [],
  8. };
  9. const entryPathToFilename = path => path === '*'
  10. ? `./src/common/safe-globals-shared.js`
  11. : `./src/${path}/safe-globals.js`;
  12. Object.entries(entryGlobals).forEach(([name, val]) => {
  13. const parts = name.split('/');
  14. if (parts[1]) parts[1] = name;
  15. val.push('*', ...parts);
  16. });
  17. /**
  18. * Adds a watcher for files in entryGlobals to properly recompile the project on changes.
  19. */
  20. function addWrapperWithGlobals(name, config, defsObj, callback) {
  21. config.module.rules.push({
  22. test: new RegExp(`/${name}/.*?\\.js$`.replace(/\//g, /[/\\]/.source)),
  23. use: [{
  24. loader: './scripts/fake-dep-loader.js',
  25. options: { files: entryGlobals[name].map(entryPathToFilename) },
  26. }],
  27. });
  28. const defsRe = new RegExp(`\\b(${
  29. Object.keys(defsObj)
  30. .join('|')
  31. .replace(/\./g, '\\.')
  32. })\\b`, 'g');
  33. const reader = () => (
  34. entryGlobals[name]
  35. .map(path => readGlobalsFile(path))
  36. .join('\n')
  37. .replace(defsRe, s => defsObj[s])
  38. );
  39. config.plugins.push(new WrapperWebpackPlugin(callback(reader)));
  40. }
  41. function getCodeMirrorThemes() {
  42. const name = 'neo.css';
  43. return fs.readdirSync(
  44. require.resolve(`codemirror/theme/${name}`).slice(0, -name.length),
  45. { withFileTypes: true },
  46. ).map(e => e.isFile() && e.name.endsWith('.css') && e.name.slice(0, -4))
  47. .filter(Boolean);
  48. }
  49. function readGlobalsFile(path, babelOpts = {}) {
  50. const { ast, code = !ast } = babelOpts;
  51. const filename = entryPathToFilename(path);
  52. const src = fs.readFileSync(filename, { encoding: 'utf8' })
  53. .replace(/\bexport\s+(function\s+(\w+))/g, 'const $2 = $1')
  54. .replace(/\bexport\s+(?=(const|let)\s)/g, '');
  55. const res = babelCore.transformSync(src, {
  56. ...babelOpts,
  57. ast,
  58. code,
  59. filename,
  60. });
  61. return ast ? res : res.code;
  62. }
  63. exports.addWrapperWithGlobals = addWrapperWithGlobals;
  64. exports.getCodeMirrorThemes = getCodeMirrorThemes;
  65. exports.readGlobalsFile = readGlobalsFile;