ScriptedAlchemy / webpack-external-import

Dynamically import modules from other webpack bundles. Painless code sharing between separate apps
BSD 3-Clause "New" or "Revised" License
415 stars 42 forks source link

Exclude some modules from being hashed. Using the original name of the request #52

Closed ScriptedAlchemy closed 4 years ago

ScriptedAlchemy commented 4 years ago

Right now react is hashed into the id, as seen below. In some cases you might not want to hash a module and instead leave it as react

{
        "order": 1,
        "name": "react",
        "id": "LDoPTt+kJa",
        "sourceFiles": [
          "vendors~main.js"
        ]
}

Implementation

Add another option to this object in src/webpack.js

this.opts = {
      publicPath: null,
      debug: debug || false,
      testPath: 'src',
      basePath: '',
      manifestName: 'unknown-project',
      fileName: 'importManifest.js',
      transformExtensions: /^(gz|map)$/i,
      writeToFileEmit: false,
      seed: null,
      filter: null,
      map: null,
      generate: null,
      hashDigest: 'base64',
      hashDigestLength: 10,
      context: null,
      sort: null,
      hashFunction: 'md4',
      serialize: (manifest) => `if(!window.entryManifest) {window.entryManifest = {}}; window.entryManifest["${opts.manifestName}"] = ${JSON.stringify(
        manifest,
        null,
        2,
      )}`,
      ...opts || {},
    };

Then youll want to look at how i track dependencies, pretty much use something similar to locate the original request, userRequest is "react"

 module.dependencies.forEach((dependency) => {
                if (this.opts.debug && (dependency.request || dependency.userRequest)) {
                  console.groupCollapsed('Dependency', dependency.userRequest, `(${dependency.request})`);
                  console.log(dependency);
                }
                const dependencyModuleSet = dependency.getReference?.()?.module;
                if (!dependencyModuleSet) return null;

Where to apply the new feature:

look for this:

compiler.hooks.compilation.tap('URLImportPlugin', (compilation) => {
        const usedIds = new Set();
        compilation.hooks.beforeModuleIds.tap(
          'URLImportPlugin',
          (modules) => {
            for (const module of modules) {
              if (module.id === null && module.resource) {
                const hash = createHash(this.opts.hashFunction);

                let resourcePath = module.resource;
                if (resourcePath.indexOf('?') > -1) {
                  resourcePath = resourcePath.split('?')[0];
                }

Id console.log(module) and you'll probably be able to find it on the object.

debugging

run yarn demo:debug, then open chrome and you should see the node logo in the inspector, click on it and itll open a console connected to node.js

ScriptedAlchemy commented 4 years ago

Done with externals PR