Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support for bun package manager #23

Closed
navidemad opened this issue Sep 12, 2023 · 4 comments
Closed

Support for bun package manager #23

navidemad opened this issue Sep 12, 2023 · 4 comments

Comments

@navidemad
Copy link

navidemad commented Sep 12, 2023

Hello, firstly thanks for your plugin.
Recently bun new package manager has been out, apparently faster than esbuild and its plugin interface is based on esbuild, but for some reason it does not works properly. For your information, there is a library called unplugin that allow to make a plugin works for multiple package manager : unjs/unplugin#329

Other links:
https://bun.sh/docs/runtime/plugins
https://dev.to/jacobandrewsky/building-universal-jsts-plugins-with-unplugin-5328
https://bun.sh/docs/bundler/plugins
https://bun.sh/docs/bundler/vs-esbuild

@Intrepidd
Copy link

I can confirm it does not work at the moment, here is the code I used and the error I got :

import rails from 'esbuild-rails'

const result = await Bun.build({
  entrypoints: [
    'app/javascript/application.js'
  ],
  naming: {
    chunk: '[name]-[hash].digested'
  },
  splitting: true,
  format: 'esm',
  outdir: 'app/assets/builds',
  plugins: [
    rails()
  ]
})
error: undefined is not an object (evaluating 'args.pluginData.path')
/path/to/my/project/undefined/**/*_controller.ts:1:0 0

Might look into it if anyone has pointers

@navidemad
Copy link
Author

navidemad commented Sep 12, 2023

I try to customize it the plugin. In bun, there is no resolveDir and neither pluginData.
My workflow of testing is:

CLI:
  rails new bun-plugin-rails-app --skip-action-mailer --skip-action-mailbox --skip-action-text --skip-active-record --skip-active-job --skip-active-storage --skip-action-cable --skip-jbuilder --skip-test --skip-system-test -j bun --main
  cd bun-plugin-rails-app

Change in Gemfile:
  gem "jsbundling-rails", github: "rails/jsbundling-rails"

CLI:
  bundle update
  rails javascript:install:bun
  bundle update
  mkdir -p app/javascript/public
  echo 'console.log(new Date().toTimeString());' >> app/javascript/public/test.js
  echo 'import "./**/*.js";' >> app/javascript/application.js
  rails g controller pages home
  bin/dev
  open http://localhost:3000/pages/home
import path from 'path';
import fg from 'fast-glob';

// Transform filenames to controller names
// [ './admin/hello_world_controller.js', ... ]
// [ 'admin--hello-world', ... ]
function convertFilenameToControllerName(filename) {
  return filename
    .replace(/^\.\//, "") // Remove ./ prefix
    .replace(/_controller.[j|t]s$/, "") // Strip _controller.js extension
    .replace(/\//g, "--") // Replace folders with -- namespaces
    .replace(/_/g, '-') //
}

// This plugin adds support for globs like "./**/*" to import an entire directory
// We can use this to import arbitrary files or Stimulus controllers and ActionCable channels
const railsPlugin = (options = { matcher: /.+\..+/ }) => {
  const resolveMap = new Map();
  return {
    name: 'rails',
    setup(build) {
      build.onResolve({ filter: /\*/ }, async (args) => {
        console.log("onResolve");
        console.log(args);
        resolveMap.set(args.importer + args.path, {
          path: args.path,
          resolveDir: path.dirname(args.importer),
        })
        return {
          path: args.importer + args.path,
          namespace: 'bun-rails',
        };
      });

      build.onLoad({ filter: /.*/, namespace: 'bun-rails' }, async (args) => {
        const resolveData = resolveMap.get(args.path);
        console.log(`Searching for '${resolveData.path}' in ${resolveData.resolveDir}`);
        let files = await fg(resolveData.path, { cwd: resolveData.resolveDir });
        files = files.sort().filter(p => options.matcher.test(p));
        files = files.map((filepath) => path.relative(resolveData.resolveDir, filepath));
        console.log(files);
        const controllerNames = files.map(convertFilenameToControllerName);

        const importerCode = `
          ${files
            .map((module, index) => `import * as module${index} from './${module}'`)
            .join(';')}
          const modules = [${controllerNames
            .map((module, index) => `{name: '${module}', module: module${index}, filename: '${files[index]}'}`)
            .join(',')}]
          export default modules;
        `;

        return { contents: importerCode };
      });
    },
  };
};

There is some logs remaining but if it can help you find a long term solution and better one.

@Jarred-Sumner
Copy link

Sorry about this. We will take a look on our end about adding these missing options to Bun.

@excid3
Copy link
Owner

excid3 commented May 28, 2024

Gonna close this as it's an issue with bun and not esbuild-rails.

@excid3 excid3 closed this as not planned Won't fix, can't repro, duplicate, stale May 28, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants