Closed davestewart closed 3 months ago
With a bit of help from Claude AI, I added the logLevel: 'debug'
setting to the esbuild config and got the following:
info Building...
● [DEBUG] Resolving import "figma-messaging" in directory "/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/src/app" of type "import-statement"
Checking for package alias matches
Failed to find any package alias matches
Read 3 entries for directory "/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/src/app"
Searching for "figma-messaging" in "node_modules" directories starting from
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/src/app"
Parsed package name "figma-messaging" and package subpath "."
Checking for a package in the directory
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging"
Read 181 entries for directory "/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules"
Resolved symlink "/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging" to
"/Volumes/Data/Work/OpenSource/Figma/figma-messaging"
The file "/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging/package.json"
exists
Read 16 entries for directory
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging"
Attempting to load "/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging" as
a file
Checking for file "figma-messaging"
Checking for file "figma-messaging.jsx"
Checking for file "figma-messaging.js"
Checking for file "figma-messaging.tsx"
Checking for file "figma-messaging.ts"
Checking for file "figma-messaging.css"
Checking for file "figma-messaging.json"
Failed to find file "figma-messaging"
Attempting to load "/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging" as
a directory
Read 16 entries for directory
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging"
Searching for main fields in
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging/package.json"
Failed to find file
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging/index.jsx"
Failed to find file
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging/index.js"
Failed to find file
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging/index.tsx"
Failed to find file
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging/index.ts"
Failed to find file
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging/index.css"
Failed to find file
"/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/node_modules/figma-messaging/index.json"
✘ [ERROR] Could not resolve "figma-messaging"
src/app/main.ts:7:29:
7 │ import { makeBus, ipc } from 'figma-messaging'
╵ ~~~~~~~~~~~~~~~~~
The "main" field here was ignored. Main fields must be configured explicitly when using the
"neutral" platform.
node_modules/figma-messaging/package.json:7:2:
7 │ "main": "dist/index.js",
╵ ~~~~~~
You can mark the path "figma-messaging" as external to exclude it from the bundle, which will
remove this error and leave the unresolved path in the bundle.
1 error
error esbuild error
Build failed with 1 error:
src/app/main.ts:7:29: ERROR: Could not resolve "figma-messaging"
info Typechecking...
Claude said of this:
Thank you for providing the verbose output. This error is actually quite informative. The issue is related to how esbuild is interpreting the "main" field in your package.json file.
The problem is that esbuild is running in "neutral" platform mode, which means it's not automatically picking up the "main" field from package.json. This is a safety feature to ensure consistent behavior across different environments. To resolve this, you have a couple of options:
In the consuming package (where you're using esbuild), you can explicitly tell esbuild which file to use for the "figma-messaging" package. Add this to your esbuild configuration:
esbuild.build({ // other options... mainFields: ['main', 'module'], // or if you're using the ESM version: // mainFields: ['module', 'main'], })
This tells esbuild to look for the 'main' field (or 'module' field) in package.json files when resolving packages. Alternatively, you can specify the platform in your esbuild configuration:
esbuild.build({ // other options... platform: 'node', // or 'browser', depending on your target environment })
This will make esbuild behave more like the standard Node.js or browser environment when resolving modules. If neither of these work, you can explicitly set the entry point for the package:
esbuild.build({ // other options... alias: { 'figma-messaging': 'figma-messaging/dist/index.js' } })
I've gone with the third option and it works.
OK, a bit more learning from my end, and I now understand the impact of the platform: "neutral"
setting:
// buildOptions
{
bundle: true,
logLevel: 'silent',
minify: false,
outfile: '/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter/build/main.js',
platform: 'neutral',
plugins: [],
stdin: {
contents: '\n' +
" const modules = {'src/app/main.ts--default':require('./src/app/main.ts')['default']};\n" +
" const commandId = (true || typeof figma.command === 'undefined' || figma.command === '' || figma.command === 'generate') ? 'src/app/main.ts--default' : figma.command;\n" +
' modules[commandId]();\n' +
' ',
resolveDir: '/Volumes/Data/Work/OpenSource/3rdParty/figma-variables-starter'
},
target: 'es2017'
}
ESBuild's docs mention:
When the platform is set to neutral:
The main fields setting is empty by default. If you want to use npm-style packages, you will likely have to configure this to be something else such as main for the standard main field used by node.
Changing the platform to browser
allows the module to be resolved OK.
I'm not so up on the mechanics of bundling (other than config and bug fixing) but is there any reason the platform is set to neutral
if the environment will effectively always be the browser (at least, Figma's sandboxed version of it) ?
Would love to hear your comments on this, even just to further my knowledge.
OK... have FINALLY got this to work without having to modify Create Figma Plugin's esbuild options.
In my module, I needed to configure the package.json
"exports"
setting:
{
"name": "figma-messaging",
"type": "module",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"files": ["dist"]
}
I have elected to keep this esm-only, as I'm fairly sure everyone will be using modern build systems.
FWIW I am using tsup to compile, and the build settings for that are:
import { defineConfig } from 'tsup'
export default defineConfig({
entry: ['src/index.ts'],
format: ['esm'],
sourcemap: true,
clean: true,
dts: true,
external: [
'@figma/plugin-typings',
],
})
Closing this now, but leaving here for future travellers.
👍
@davestewart – Thanks for writing this up! Maybe the platform
config should have been set to browser
; definitely needs further investigation. IIRC there was some nuance with how code was being output if browser
is set that caused me to use the neutral
option instead
No problem.
If you need any help, let me know.
FWIW, I think the build config docs could do with being promoted from being buried in Recipes to somewhere in Config, or a Setup section?
Only because Recipes feels (by location) like tasks you might do once you're up and running.
I'm trying to compile using a local npm module I'm working on.
I symlinked the module using
npm link
in the module's folder, thennpm link figma-messaging
in the figma plugin.The module is there, and I can
ls
it:My IDE can see it fine, and I can import and use.
But when I build:
I have tried a few things with custom esbuild config as suggested in the docs, but no luck.
Any ideas?