jfortunato / esbuild-plugin-manifest

Esbuild plugin for building an asset manifest file.
MIT License
31 stars 5 forks source link

Map Esbuild Autogenerated Sibling CSS Output Files Into manifest.json #3

Closed maxschridde1494 closed 3 years ago

maxschridde1494 commented 3 years ago

When a .js entry file imports CSS, esbuild will automatically generate a sibling css output file as noted here. Since these css build files are autogenerated (i.e. not passed through as initial entrypoints), they are not included in the generated manifest file. This line appears to be the culprit. Ideally, these autogenerated build files would also be included within the manifest.json file.

Richard87 commented 3 years ago

I just hit this bug to when I noticed the generated css files are not imported inside the js, and not referenced in the manifest.json file

Richard87 commented 3 years ago

I think the solution would be to recursivly search the meta-file/object for the entrypoint that references the main css output file (if it's not itself a entrypoint)

jfortunato commented 3 years ago

Esbuild can output all sorts of auxiliary or 'sibling' files that are not entry points themselves. These may include things like images, fonts, sourcemap files, and CSS files. I don't think we want the generated manifest file to contain every possible output file (at least not by default), but we may want to include specific types like CSS.

Richard87 commented 3 years ago

Hi @maxschridde1494 ! A fix is pushed to the devlop branch, do you mind installing it and making sure everything works as expected? :)

yarn add esbuild-plugin-manifest@https://github.com/jfortunato/esbuild-plugin-manifest#develop
// And/or
yarn upgrade esbuild-plugin-manifest
jfortunato commented 3 years ago

I don't think it will currently work out of the box when installing from github like that, as the compiled typescript files under lib/ won't exist. I'll be making an official release soon however.

jfortunato commented 3 years ago

OK starting with v0.3.0 it will include "sibling" css files in the manifest.

maxschridde1494 commented 3 years ago

Great. v0.3.0 is successfully mapping the sibling css files in our case. Thanks for the quick turn around here.

maxschridde1494 commented 3 years ago

Upon further inspection of the generated manifest, I'm actually seeing a bug. Here is the generated manifest:

{
  "app/javascript/packs/application.tsx": "public/esbuild/application-TVIY7IJP.js",
  "app/javascript/packs/application.css": "public/esbuild/application-5L6MECDN.css",
  "app/javascript/packs/dashboard.tsx": "public/esbuild/dashboard-ISS3O72C.js",
  "app/javascript/packs/dashboard.css": "public/esbuild/admin-2AA73QTM.css", // this should point to dashboard-[hash].css
  "app/javascript/packs/admin.css": "public/esbuild/admin-2AA73QTM.css",
  "app/javascript/packs/admin.tsx": "public/esbuild/admin-V2DKYWTC.js"
}

Notice that the dashboard.css entrypoint points to the admin css sibling instead of the generated dashboard css sibling. The only option we are passing through to the plugin is the custom manifest filename.

jfortunato commented 3 years ago

@Richard87 I've made an update to the develop branch. Can you confirm everything is still working for your usecase?

Richard87 commented 3 years ago

@jfortunato Yup, can confirm, the latest update works nicely here!

{
  "../assets/FormTask/App.js": "build2/FormTask/App-HIK4HSCH.js",
  "../assets/FormTask/App.css": "build2/FormTask/App-JLWUV65U.css",
  "../assets/Search/App.js": "build2/Search/App-B3BGZYV5.js",
  "../assets/App.js": "build2/App-VRKFLDW4.js",
  "../assets/App.css": "build2/App-HAN3VM5J.css",
  "../assets/State/index.js": "build2/State/index-VGXKL2QC.js",
  "../assets/State/index.css": "build2/State/index-RUHF5HFA.css"
}

(I can't test it yet since the lib files are missing, but everything looks nice!)

Also, interesting strategy to find sibling files!

jfortunato commented 3 years ago

@maxschridde1494 Should be fixed in v0.4.1

maxschridde1494 commented 3 years ago

I'm still having issues. This is the esbuild outdir:

➜ ls public/esbuild/**
public/esbuild/admin-FUGH2KFH.css
public/esbuild/admin-GUBUMFTO.js
public/esbuild/admin-GUBUMFTO.js.map
public/esbuild/application-5L6MECDN.css
public/esbuild/application-TVIY7IJP.js
public/esbuild/application-TVIY7IJP.js.map
public/esbuild/dashboard-57NKOQWU.css
public/esbuild/dashboard-ABZWCREF.js
public/esbuild/dashboard-ABZWCREF.js.map
public/esbuild/applets/join_pta-RYNUBROZ.css
public/esbuild/applets/join_pta-NEDZUVBV.js     
public/esbuild/applets/join_pta-NEDZUVBV.js.map 

And this is the error the plugin is emitting:

➜ yarn build
esbuild start...
building with esbuildOpts {"entryPoints":["app/javascript/packs/application","app/javascript/packs/dashboard","app/javascript/packs/applets/join_pta","app/javascript/packs/admin"],"entryNames":"[dir]/[name]-[hash]","outdir":"public/esbuild"} and manifestOpts {"filename":"packs-manifest.json"}...

 > /Users/maxschridde/dev/totem/node_modules/esbuild-plugin-manifest/lib/index.js:76:26: error: [plugin: manifest] There is a conflicting manifest key for 'app/javascript/packs/application.tsx'.
    76 │                     throw new Error(`There is a conflicting manifest key for '${input}'.`);
       ╵                           ^
    at addMapping (/Users/maxschridde/dev/totem/node_modules/esbuild-plugin-manifest/lib/index.js:76:27)
    at /Users/maxschridde/dev/totem/node_modules/esbuild-plugin-manifest/lib/index.js:98:21
    at /Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:921:21
    at runOnEndCallbacks (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:926:11)
    at buildResponseToResult (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1123:7)
    at /Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1230:14
    at /Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:606:9
    at handleIncomingPacket (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:703:9)
    at Socket.readFromStdout (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:573:7)
    at Socket.emit (node:events:369:20)

   /Users/maxschridde/dev/totem/node_modules/esbuild-plugin-manifest/lib/index.js:56:14: note: This error came from the "onEnd" callback registered here
    56 │         build.onEnd((result) => {
       ╵               ~~~~~
    at setup (/Users/maxschridde/dev/totem/node_modules/esbuild-plugin-manifest/lib/index.js:56:15)
    at handlePlugins (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:733:23)
    at Object.buildOrServe (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1018:7)
    at /Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1742:17
    at new Promise (<anonymous>)
    at Object.build (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1741:14)
    at Object.build (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1617:51)
    at build (/Users/maxschridde/dev/totem/esbuild.js:18:6)
    at /Users/maxschridde/dev/totem/esbuild.js:76:9

Error: Build failed with 1 error:
/Users/maxschridde/dev/totem/node_modules/esbuild-plugin-manifest/lib/index.js:76:26: error: [plugin: manifest] There is a conflicting manifest key for 'app/javascript/packs/application.tsx'.
    at failureErrorWithLog (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1443:15)
    at /Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1125:28
    at processTicksAndRejections (node:internal/process/task_queues:94:5) {
  errors: [
    {
      pluginName: 'manifest',
      text: "There is a conflicting manifest key for 'app/javascript/packs/application.tsx'.",
      location: [Object],
      notes: [Array],
      detail: Error: There is a conflicting manifest key for 'app/javascript/packs/application.tsx'.
          at addMapping (/Users/maxschridde/dev/totem/node_modules/esbuild-plugin-manifest/lib/index.js:76:27)
          at /Users/maxschridde/dev/totem/node_modules/esbuild-plugin-manifest/lib/index.js:98:21
          at /Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:921:21
          at runOnEndCallbacks (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:926:11)
          at buildResponseToResult (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1123:7)
          at /Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:1230:14
          at /Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:606:9
          at handleIncomingPacket (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:703:9)
          at Socket.readFromStdout (/Users/maxschridde/dev/totem/node_modules/esbuild/lib/main.js:573:7)
          at Socket.emit (node:events:369:20)
    }
  ]
}
esbuild complete...
✨  Done in 1.93s.
jfortunato commented 3 years ago

@maxschridde1494 would you mind sharing the options you are passing to esbuild?

jfortunato commented 3 years ago

@maxschridde1494 actually nevermind they are already included in the error message

maxschridde1494 commented 3 years ago

sure. there are actually more. here is the full esbuild opts object


{
          bundle: true,
          minify: true,
          sourcemap: true,
          watch: watching,
          nodePaths: [ ... ],
          loader: {
            '.js': 'js',
            '.jsx': 'jsx',
            '.tsx': 'tsx',
            '.ts': 'ts',
            '.png': 'dataurl',
            '.woff': 'dataurl',
            '.woff2': 'dataurl',
            '.eot': 'dataurl',
            '.ttf': 'dataurl',
            '.svg': 'dataurl',
          },
          plugins: [
            manifestPlugin({ filename: '' }),
            sassPlugin(),
            NodeGlobalsPolyfillPlugin(opts),
          ],
          define: { ... },
          entryPoints: [ ... ],
          entryNames: '[dir]/[name]-[hash]'
          outdir: ''
}
jfortunato commented 3 years ago

@maxschridde1494 Thank you. I've issued an update that I'm hoping will fix your scenario.