| OLD | NEW | 
| (Empty) |  | 
 |    1 /* | 
 |    2  * This file is part of Adblock Plus <https://adblockplus.org/>, | 
 |    3  * Copyright (C) 2006-present eyeo GmbH | 
 |    4  * | 
 |    5  * Adblock Plus is free software: you can redistribute it and/or modify | 
 |    6  * it under the terms of the GNU General Public License version 3 as | 
 |    7  * published by the Free Software Foundation. | 
 |    8  * | 
 |    9  * Adblock Plus is distributed in the hope that it will be useful, | 
 |   10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
 |   11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
 |   12  * GNU General Public License for more details. | 
 |   13  * | 
 |   14  * You should have received a copy of the GNU General Public License | 
 |   15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
 |   16  */ | 
 |   17  | 
 |   18 "use strict"; | 
 |   19  | 
 |   20 const path = require("path"); | 
 |   21 const process = require("process"); | 
 |   22  | 
 |   23 const MemoryFS = require("memory-fs"); | 
 |   24 const webpack = require("webpack"); | 
 |   25  | 
 |   26 // We read the configuration from STDIN rather than as an argument to improve | 
 |   27 // the output on error. Otherwise the (fairly huge) configuration is printed | 
 |   28 // along with the actual error message. | 
 |   29 let inputChunks = []; | 
 |   30 process.stdin.setEncoding("utf-8"); | 
 |   31 process.stdin.on("data", chunk => { inputChunks.push(chunk); }); | 
 |   32 process.stdin.on("end", () => | 
 |   33 { | 
 |   34   let {bundles, extension_path, | 
 |   35        info_module, resolve_paths} = JSON.parse(inputChunks.join("")); | 
 |   36  | 
 |   37   // The contents of the info module is passed to us as a string from the Python | 
 |   38   // packager and we pass it through to our custom loader now so it is available | 
 |   39   // at bundle time. | 
 |   40   require("./info-loader").setInfoModule(info_module); | 
 |   41  | 
 |   42   // Since the cost of starting Node.js and loading all the modules is hugely | 
 |   43   // larger than actually producing bundles we avoid paying it multiple times, | 
 |   44   // instead producing all the bundles in one go. | 
 |   45   let options = []; | 
 |   46   for (let {bundle_name, entry_points} of bundles) | 
 |   47   { | 
 |   48     options.push({ | 
 |   49       context: extension_path, | 
 |   50       devtool: "source-map", | 
 |   51       module: { | 
 |   52         rules: [{ | 
 |   53           include: path.join(__dirname, "info.js"), | 
 |   54           use: ["info-loader"] | 
 |   55         }] | 
 |   56       }, | 
 |   57       entry: entry_points, | 
 |   58       output: { | 
 |   59         path: "/", | 
 |   60         filename: bundle_name | 
 |   61       }, | 
 |   62       resolve: { | 
 |   63         modules: resolve_paths, | 
 |   64         alias: { | 
 |   65           // To use our custom loader for the info module we must first set up | 
 |   66           // an alias to a file that exists. | 
 |   67           info$: path.join(__dirname, "info.js"), | 
 |   68           // Prevent builtin Node.js modules from being used instead of our own | 
 |   69           // when the names clash. Once relative paths are used this won't be | 
 |   70           // necessary. | 
 |   71           url$: "url.js", | 
 |   72           events$: "events.js", | 
 |   73           punycode$: "punycode.js" | 
 |   74         }, | 
 |   75         plugins: [ | 
 |   76           function() | 
 |   77           { | 
 |   78             // Our old module system in packagerChrome.py used to prefix | 
 |   79             // module names with the name of their parent directory and an | 
 |   80             // underscore - but only when that directory wasn't called | 
 |   81             // "lib". This plugin is for backwards compatability, but can | 
 |   82             // be removed once use of that deprecated syntax has been | 
 |   83             // replaced. | 
 |   84             this.plugin("described-resolve", (request, callback) => | 
 |   85             { | 
 |   86               let target = request.request; | 
 |   87  | 
 |   88               let prefixIndex = target.indexOf("_"); | 
 |   89               if (prefixIndex == -1) | 
 |   90                 return callback(); | 
 |   91  | 
 |   92               let prefix = target.substring(0, prefixIndex); | 
 |   93               if (prefix == "lib") | 
 |   94                 return callback(); | 
 |   95  | 
 |   96               let fixedTarget = path.join(prefix, | 
 |   97                                            target.substring(prefixIndex + 1)); | 
 |   98               return this.doResolve( | 
 |   99                 "resolve", Object.assign({}, request, {request: fixedTarget}), | 
 |  100                 "Changed prefixed path using legacy buildtools syntax from " + | 
 |  101                 target + " to " + fixedTarget, | 
 |  102                 callback | 
 |  103               ); | 
 |  104             }); | 
 |  105           } | 
 |  106         ] | 
 |  107       }, | 
 |  108       resolveLoader: { | 
 |  109         modules: [path.resolve(__dirname)] | 
 |  110       } | 
 |  111     }); | 
 |  112   } | 
 |  113  | 
 |  114   // Based on this example | 
 |  115   // https://webpack.js.org/api/node/#custom-file-systems | 
 |  116   let memoryFS = new MemoryFS(); | 
 |  117   let webpackCompiler = webpack(options); | 
 |  118  | 
 |  119   webpackCompiler.outputFileSystem = memoryFS; | 
 |  120   webpackCompiler.run((err, stats) => | 
 |  121   { | 
 |  122     // Error handling is based on this example | 
 |  123     // https://webpack.js.org/api/node/#error-handling | 
 |  124     if (err) | 
 |  125     { | 
 |  126       let reason = err.stack || err; | 
 |  127       if (err.details) | 
 |  128         reason += "\n" + err.details; | 
 |  129       throw new Error(reason); | 
 |  130     } | 
 |  131     else if (stats.hasErrors()) | 
 |  132       throw new Error(stats.toJson().errors.join("\n")); | 
 |  133     else | 
 |  134     { | 
 |  135       let output = {}; | 
 |  136       let files = output.files = {}; | 
 |  137  | 
 |  138       for (let config of options) | 
 |  139       { | 
 |  140         let filepath = path.join(config.output.path, config.output.filename); | 
 |  141         let relativeFilepath = path.relative("/", filepath); | 
 |  142         files[relativeFilepath] = memoryFS.readFileSync(filepath, "utf-8"); | 
 |  143         files[relativeFilepath + ".map"] = memoryFS.readFileSync( | 
 |  144           filepath + ".map", "utf-8" | 
 |  145         ); | 
 |  146       } | 
 |  147  | 
 |  148       // We provide a list of all the bundled files, so the packager can avoid | 
 |  149       // including them again outside of a bundle. Otherwise we end up including | 
 |  150       // duplicate copies in our builds. | 
 |  151       let included = new Set(); | 
 |  152       for (let bundle of stats.toJson().children) | 
 |  153       { | 
 |  154         for (let chunk of bundle.chunks) | 
 |  155         { | 
 |  156           for (let module of chunk.modules) | 
 |  157           { | 
 |  158             if (!module.name.startsWith("multi ")) | 
 |  159               included.add(path.relative(extension_path, module.name)); | 
 |  160           } | 
 |  161         } | 
 |  162       } | 
 |  163       output.included = Array.from(included); | 
 |  164  | 
 |  165       console.log(JSON.stringify(output)); | 
 |  166     } | 
 |  167   }); | 
 |  168 }); | 
| OLD | NEW |