webpack.conf.js 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. const webpack = require('webpack');
  2. const { ListBackgroundScriptsPlugin } = require('./manifest-helper');
  3. const { addWrapperWithGlobals, getCodeMirrorThemes } = require('./webpack-util');
  4. const ProtectWebpackBootstrapPlugin = require('./webpack-protect-bootstrap-plugin');
  5. const { getVersion } = require('./version-helper');
  6. const { configLoader } = require('./config-helper');
  7. const { getBaseConfig, getPageConfig, isProd } = require('./webpack-base');
  8. // Avoiding collisions with globals of a content-mode userscript
  9. const INIT_FUNC_NAME = '**VMInitInjection**';
  10. const VAULT_ID = 'VAULT_ID';
  11. const PAGE_MODE_HANDSHAKE = 'PAGE_MODE_HANDSHAKE';
  12. const VM_VER = getVersion();
  13. global.localStorage = {}; // workaround for node 25 and HtmlWebpackPlugin's `...global`
  14. configLoader
  15. // Default values
  16. .add({
  17. DEBUG: false,
  18. })
  19. // Load from `./.env`
  20. .envFile()
  21. // Load from `process.env`
  22. .env()
  23. // Override values
  24. .add({
  25. VM_VER,
  26. });
  27. const pickEnvs = (items) => {
  28. return Object.assign({}, ...items.map(key => ({
  29. [`process.env.${key}`]: JSON.stringify(configLoader.get(key)),
  30. })));
  31. };
  32. const defsObj = {
  33. ...pickEnvs([
  34. 'DEBUG',
  35. 'VM_VER',
  36. 'SYNC_GOOGLE_DESKTOP_ID',
  37. 'SYNC_GOOGLE_DESKTOP_SECRET',
  38. 'SYNC_ONEDRIVE_CLIENT_ID',
  39. 'SYNC_DROPBOX_CLIENT_ID',
  40. ]),
  41. 'process.env.INIT_FUNC_NAME': JSON.stringify(INIT_FUNC_NAME),
  42. 'process.env.CODEMIRROR_THEMES': JSON.stringify(getCodeMirrorThemes()),
  43. 'process.env.DEV': JSON.stringify(!isProd),
  44. 'process.env.TEST': JSON.stringify(process.env.BABEL_ENV === 'test'),
  45. };
  46. // avoid running webpack bootstrap in a potentially hacked environment
  47. // after documentElement was replaced which triggered reinjection of content scripts
  48. const skipReinjectionHeader = `{
  49. const INIT_FUNC_NAME = '${INIT_FUNC_NAME}';
  50. if (window[INIT_FUNC_NAME] !== 1)`;
  51. const buildConfig = (page, entry, init) => {
  52. const config = entry ? getBaseConfig() : getPageConfig();
  53. config.plugins.push(new webpack.DefinePlugin({
  54. ...defsObj,
  55. // Conditional compilation to remove unsafe and unused stuff from `injected`
  56. 'process.env.IS_INJECTED': JSON.stringify(/injected/.test(page) && page),
  57. }));
  58. if (typeof entry === 'string') {
  59. config.entry = { [page]: entry };
  60. }
  61. if (!entry) init = page;
  62. if (init) init(config);
  63. return config;
  64. };
  65. module.exports = [
  66. buildConfig((config) => {
  67. addWrapperWithGlobals('common', config, defsObj, getGlobals => ({
  68. header: () => `{ ${getGlobals()}`,
  69. footer: '}',
  70. test: /^(?!injected|public).*\.js$/,
  71. }));
  72. config.plugins.push(new ListBackgroundScriptsPlugin({
  73. minify: false, // keeping readable
  74. }));
  75. (config.ignoreWarnings ??= []).push({
  76. // suppressing a false warning (the HTML spec allows it) as we don't need SSR
  77. message: /<tr> cannot be child of <table>/,
  78. });
  79. }),
  80. buildConfig('injected', './src/injected', (config) => {
  81. config.plugins.push(new ProtectWebpackBootstrapPlugin());
  82. addWrapperWithGlobals('injected/content', config, defsObj, getGlobals => ({
  83. header: () => `${skipReinjectionHeader} { ${getGlobals()}`,
  84. footer: '}}',
  85. }));
  86. }),
  87. buildConfig('injected-web', './src/injected/web', (config) => {
  88. config.output.libraryTarget = 'commonjs2';
  89. config.plugins.push(new ProtectWebpackBootstrapPlugin());
  90. addWrapperWithGlobals('injected/web', config, defsObj, getGlobals => ({
  91. header: () => `${skipReinjectionHeader}
  92. window[INIT_FUNC_NAME] = function (IS_FIREFOX,${PAGE_MODE_HANDSHAKE},${VAULT_ID}) {
  93. const module = { __proto__: null };
  94. ${getGlobals()}`,
  95. footer: `
  96. const { exports } = module;
  97. return exports.__esModule ? exports.default : exports;
  98. }};0;`,
  99. }));
  100. }),
  101. ];