You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

91 lines
1.9 KiB

4 years ago
  1. 'use strict';
  2. const path = require('path');
  3. const fs = require('fs');
  4. function getAllFiles(root) {
  5. var res = [],
  6. files = fs.readdirSync(root);
  7. files.forEach(function (file) {
  8. var pathname = root + '/' + file,
  9. stat = fs.lstatSync(pathname);
  10. if (!stat.isDirectory()) {
  11. res.push(pathname);
  12. } else {
  13. res = res.concat(getAllFiles(pathname));
  14. }
  15. });
  16. return res
  17. }
  18. function replace(file, rules) {
  19. const src = path.resolve(file);
  20. let template = fs.readFileSync(src, 'utf8');
  21. template = rules.reduce(
  22. (template, rule) => template.replace(
  23. rule.search, (typeof rule.replace === 'string' ? rule.replace : rule.replace.bind(global))
  24. ),
  25. template
  26. );
  27. fs.writeFileSync(src, template);
  28. }
  29. function ReplaceInFilePlugin(options = []) {
  30. this.options = options;
  31. };
  32. ReplaceInFilePlugin.prototype.apply = function (compiler) {
  33. const root = compiler.options.context;
  34. const done = (statsData) => {
  35. if (statsData.hasErrors()) {
  36. return
  37. }
  38. this.options.forEach(option => {
  39. const dir = option.dir || root;
  40. const files = option.files;
  41. if(option.files){
  42. const files = option.files;
  43. if(Array.isArray(files) && files.length) {
  44. files.forEach(file => {
  45. replace(path.resolve(dir, file), option.rules);
  46. })
  47. }
  48. } else if (option.test) {
  49. const test = option.test;
  50. const testArray = Array.isArray(test) ? test : [test];
  51. const files = getAllFiles(dir);
  52. files.forEach(file => {
  53. const match = testArray.some((test, index, array) => {
  54. return test.test(file);
  55. })
  56. if (!match) {
  57. return;
  58. }
  59. replace(file, option.rules);
  60. })
  61. } else {
  62. const files = getAllFiles(dir);
  63. files.forEach(file => {
  64. replace(file, option.rules);
  65. })
  66. }
  67. })
  68. }
  69. if (compiler.hooks) {
  70. const plugin = {
  71. name: "ReplaceInFilePlugin"
  72. };
  73. compiler.hooks.done.tap(plugin, done);
  74. } else {
  75. compiler.plugin('done', done);
  76. }
  77. };
  78. module.exports = ReplaceInFilePlugin;