webpack-util.js 2.2 KB

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