Skip to main content

WHAT I WANT TO ACCOMPLISH


Please excuse my poor English.

I want to output CSV files for items such as Text in Figma, but I wanted to separate the files, so I used this as a reference to set up ts-loader and webpack.

I am new to developing Figma plug-ins, but I managed to complete the process of compiling text and other items and outputting them to the console.

After that, I encountered an error where the output in CSV would use fs, but here I encountered an error where fs could not be imported.


THE PROBLEM AREA


//The problem area
import * as fs from 'fs'; // Here!!
export class DownloadCSV{
......

public save(filename: string = "out.csv"){
fs.writeFileSync(filename, this.text);
}
}

//manifest.json
{
"name": "XXX",
"id": "1338758441514588489",
"api": "1.0.0",
"main": "dist/main.js",
"capabilities": [],
"enableProposedApi": false,
"editorType": [
"figma",
"figjam"
],
"ui": "dist/ui.html",
"networkAccess": {
"allowedDomains": [
"none"
]
}
}

package.json
{
"name": "XXX",
"version": "1.0.0",
"description": "XXX",
"main": "dist/main.js",
"private": true,
"scripts": {
"analyze": "npx webpack --mode production --profile --json > profile.json && npx webpack-bundle-analyzer profile.json build",
"build": "npx webpack --mode production",
"build:watch": "npx webpack --mode development --watch",
"lint": "npx eslint",
"prettier:format": "npx prettier --write 'src/**/*.{js,jsx,ts,tsx,css,json}'"
},
"author": "",
"license": "",
"devDependencies": {
"@figma/plugin-typings": "^1.85.0",
"@types/express": "^4.17.21",
"@types/node": "^20.11.20",
"ts-loader": "^9.5.1",
"typescript": "^5.3.3",
"webpack": "^5.90.3",
"webpack-cli": "^5.1.4"
},
"dependencies": {
"@types/fs-extra": "^11.0.4",
"@types/react": "^18.2.60",
"@types/react-dom": "^18.2.19",
"@types/three": "^0.161.2",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"three": "^0.150.1"
}
}

//tsconfig.json
{
"compilerOptions": {
// Three.jsがES5未サポートなので、割り切って比較的新しい仕様でビルドする
"target": "ES2015",
// TSのモジュールはES Modulesとして出力
"module": "ES2015",
// JSXの書式を有効に設定
"jsx": "react-jsx",
// node_modules からライブラリを読み込む
"moduleResolution": "node",
// これの設定も必要 デフォルトインポートの有効化
"allowSyntheticDefaultImports": true,
// 厳密モード
"strict": true,
"lib":
"ES2023",
"DOM"
],
"typeRoots": h
"./node_modules/@types",
"./node_modules/@figma"
],
},
"include": 0"src/**/*.ts"],
}

//webpack.config.js
module.exports = {
// モード値を production に設定すると最適化された状態で、
// development に設定するとソースマップ有効でJSファイルが出力される
mode: 'development',

// ↓コメントを解除すればビルド時のエラーは消えますが、Figma実行時に「requireが使われている」というエラーが発生します。
//target: 'node',

// メインとなるJavaScriptファイル(エントリーポイント)
entry: './src/main.ts',
output: {
// 出力ファイルのディレクトリ名
path: `${__dirname}/dist`,
// 出力ファイル名
filename: "main.js"
},
module: {
rules:
{
// 拡張子 .ts の場合
test: /\.(js|ts|tsx)$/,
//exclude: /node_modules/,
// TypeScript をコンパイルする
use: 'ts-loader',
},
],
},

// import 文で .ts ファイルを解決するため
// これを定義しないと import 文で拡張子を書く必要が生まれる。
// フロントエンドの開発では拡張子を省略することが多いので、
// 記載したほうがトラブルに巻き込まれにくい。
resolve: {
// 拡張子を配列で指定
extensions: ".ts", ".tsx", ".js", ".json"],
//modules: `${__dirname}/src`, 'node_modules']
},
// ES5(IE11等)向けの指定(webpack 5以上で必要)
target: "web", "es5"],
};

PROBLEM/ERROR MESSAGE BEING ENCOUNTERED


//console
PS C:\Users\XXXX> npm run build
Debugger attached.

> plugin@1.0.0 build
> npx webpack --mode production

Debugger attached.
Debugger attached.
assets by status 2 KiB cached] 1 asset
orphan modules 4.52 KiB rorphan] 3 modules
./src/main.ts + 3 modules 5.94 KiB tbuilt] :code generated]

ERROR in ./src/DownloadCSV.ts 1:0-25
Module not found: Error: Can't resolve 'fs' in 'C:\Users\XXXX\src'
resolve 'fs' in 'C:\Users\XXXX\src'
Parsed request is a module
using description file: C:\Users\XXXX\package.json (relative path: ./src)
Field 'browser' doesn't contain a valid alias configuration
resolve as module
C:\Users\XXXX\src\node_modules doesn't exist or is not a directory
looking for modules in C:\Users\XXXX\node_modules
single file module
using description file: C:\Users\XXXX\package.json (relative path: ./node_modules/fs)
no extension
Field 'browser' doesn't contain a valid alias configuration
C:\Users\XXXX\node_modules\fs doesn't exist
.ts
Field 'browser' doesn't contain a valid alias configuration
C:\Users\XXXX\node_modules\fs.ts doesn't exist
.tsx
Field 'browser' doesn't contain a valid alias configuration
C:\Users\XXXX\node_modules\fs.tsx doesn't exist
.js
Field 'browser' doesn't contain a valid alias configuration
C:\Users\XXXX\node_modules\fs.js doesn't exist
.json
Field 'browser' doesn't contain a valid alias configuration
C:\Users\XXXX\node_modules\fs.json doesn't exist
C:\Users\XXXX\node_modules\fs doesn't exist

C:\Users\node_modules doesn't exist or is not a directory
C:\node_modules doesn't exist or is not a directory
@ ./src/SearchScreen.ts 2:0-38 13:20-36
@ ./src/main.ts 1:0-37 36:24-39

webpack 5.90.3 compiled with 1 error in 2429 ms
Waiting for the debugger to disconnect...
Waiting for the debugger to disconnect...
Waiting for the debugger to disconnect...

WHAT I TRIED


I have searched for 2 weeks on stackOverflow and other sites to find the cause, but I am frustrated.

I am wondering if Figma and Webpack are incompatible, but I have no idea what the cause is or how to fix it. I have no idea what the cause is or how to fix it, so I am asking for your advice on what I should do.

Thank you in advance for your answer!!


ADDITIONAL INFORMATION (FW/TOOL VERSION, ETC.)


node v20.11.0

Hi,


I tried to resolve the same issue of yours and found that it seems impossible to export data files directly from Figma plug-in.


So I made a simple server which just saves data from Figma plug-in into local files. My test Figma plug-in extracts and sends the data to the server using Figma’s Fetch APIs.


I hope this would help you.


I am facing the same issue, and think that the ‘fs’ module is not available in the Figma console, because:

> const fs = await import('fs');

returns the error:

Uncaught TypeError: Failed to resolve module specifier 'fs'


@YoonHo_Lim your solution seems very useful. Would you be able to share more details / pointers about how you created the server and about the fetch() API call you used?


Thanks!


Reply