0
Fork 0
mirror of https://github.com/penpot/penpot-exporter-figma-plugin.git synced 2024-12-22 05:33:02 -05:00

replace webpack for esbuild (#17)

This commit is contained in:
Jordi Sala Morales 2024-04-12 18:52:19 +02:00 committed by GitHub
parent ded8b1c657
commit 5c58d53e60
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
98 changed files with 2159 additions and 2609 deletions

View file

@ -1,3 +1,3 @@
node_modules node_modules
dist dist
src/ui/lib/penpot.js ui-src/lib/penpot.js

View file

@ -1,4 +1,4 @@
node_modules node_modules
dist dist
src/ui/lib/penpot.js ui-src/lib/penpot.js
LICENSE LICENSE

View file

@ -3,7 +3,7 @@
"id": "", "id": "",
"api": "1.0.0", "api": "1.0.0",
"main": "dist/code.js", "main": "dist/code.js",
"ui": "dist/ui.html", "ui": "dist/index.html",
"editorType": ["figma", "figjam"], "editorType": ["figma", "figjam"],
"documentAccess": "dynamic-page" "documentAccess": "dynamic-page"
} }

4546
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -3,18 +3,22 @@
"version": "0.0.1", "version": "0.0.1",
"description": "Penpot exporter", "description": "Penpot exporter",
"type": "module", "type": "module",
"main": "code.js",
"scripts": { "scripts": {
"build": "webpack", "build": "npm run build:ui && npm run build:main -- --minify",
"build:main": "esbuild plugin-src/code.ts --bundle --outfile=dist/code.js",
"build:ui": "vite build --minify esbuild --emptyOutDir=false",
"build:watch": "concurrently -n widget,iframe \"npm run build:main -- --watch\" \"npm run build:ui -- --watch\"",
"dev": "concurrently -n tsc,build,vite 'npm:tsc:watch' 'npm:build:watch' 'vite'",
"watch": "webpack watch", "watch": "webpack watch",
"lint": "run-p lint:*", "lint": "concurrently \"npm:lint:*\"",
"lint:eslint": "eslint .", "lint:eslint": "eslint .",
"lint:stylelint": "stylelint src/ui/**.css", "lint:stylelint": "stylelint ui-src/**.css",
"lint:prettier": "prettier --check .", "lint:prettier": "prettier --check .",
"lint:tsc": "tsc --noEmit --pretty false", "lint:tsc-ui": "tsc -p ui-src/tsconfig.json --noEmit --pretty false",
"fix-lint": "run-p fix-lint:*", "lint:tsc-plugin": "tsc -p plugin-src/tsconfig.json --noEmit --pretty false",
"fix-lint": "concurrently \"npm:fix-lint:*\"",
"fix-lint:eslint": "eslint . --fix", "fix-lint:eslint": "eslint . --fix",
"fix-lint:stylelint": "stylelint src/ui/**.css --fix", "fix-lint:stylelint": "stylelint ui-src/**.css --fix",
"fix-lint:prettier": "prettier --write ." "fix-lint:prettier": "prettier --write ."
}, },
"author": "Kaleidos", "author": "Kaleidos",
@ -33,23 +37,21 @@
"@types/react-dom": "^18.2", "@types/react-dom": "^18.2",
"@typescript-eslint/eslint-plugin": "^7.5", "@typescript-eslint/eslint-plugin": "^7.5",
"@typescript-eslint/parser": "^7.5", "@typescript-eslint/parser": "^7.5",
"css-loader": "^6.10", "@vitejs/plugin-react-swc": "^3.6",
"concurrently": "^8.2",
"esbuild": "^0.20",
"eslint": "^8.57", "eslint": "^8.57",
"eslint-config-prettier": "^9.1", "eslint-config-prettier": "^9.1",
"eslint-plugin-prettier": "^5.1", "eslint-plugin-prettier": "^5.1",
"eslint-plugin-react": "^7.34", "eslint-plugin-react": "^7.34",
"html-webpack-inline-source-plugin": "0.0.10",
"html-webpack-plugin": "^5.6",
"npm-run-all2": "^6.1",
"prettier": "^3.2", "prettier": "^3.2",
"react-dev-utils": "^12.0",
"style-loader": "^3.3",
"stylelint": "^16.3", "stylelint": "^16.3",
"stylelint-config-standard": "^36.0", "stylelint-config-standard": "^36.0",
"ts-loader": "^9.5",
"tsconfig-paths-webpack-plugin": "^4.1", "tsconfig-paths-webpack-plugin": "^4.1",
"typescript": "^5.4", "typescript": "^5.4",
"webpack": "^5.91", "vite": "^5.2",
"webpack-cli": "^5.1" "vite-plugin-singlefile": "^2.0",
"vite-plugin-svgr": "^4.2",
"vite-tsconfig-paths": "^4.3"
} }
} }

10
plugin-src/tsconfig.json Normal file
View file

@ -0,0 +1,10 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"target": "es6",
"lib": ["es6"],
"strict": true,
"typeRoots": ["../node_modules/@figma"],
"moduleResolution": "Node"
}
}

View file

@ -1 +0,0 @@
<div id="penpot-export-page"></div>

9
tsconfig.base.json Normal file
View file

@ -0,0 +1,9 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@plugin/*": ["./plugin-src/*"],
"@ui/*": ["./ui-src/*"]
}
}
}

View file

@ -1,19 +0,0 @@
{
"compilerOptions": {
"esModuleInterop": true,
"isolatedModules": true,
"skipLibCheck": true,
"jsx": "react-jsx",
"lib": ["DOM", "ES6"],
"target": "es2017",
"module": "ESNext",
"moduleResolution": "Node10",
"strict": true,
"typeRoots": ["src/ui/lib/penpot.d.ts", "node_modules/@figma", "node_modules/@types"],
"resolveJsonModule": true,
"paths": {
"@plugin/*": ["./src/plugin/*"],
"@ui/*": ["./src/ui/*"]
}
}
}

View file

@ -5,6 +5,8 @@ import { createPenpotFile } from '@ui/converters';
import { PenpotDocument } from '@ui/lib/types/penpotDocument'; import { PenpotDocument } from '@ui/lib/types/penpotDocument';
import { validateFont } from '@ui/validators'; import { validateFont } from '@ui/validators';
import Logo from './logo.svg?react';
export const PenpotExporter = () => { export const PenpotExporter = () => {
const [missingFonts, setMissingFonts] = useState(new Set<string>()); const [missingFonts, setMissingFonts] = useState(new Set<string>());
const [exporting, setExporting] = useState(false); const [exporting, setExporting] = useState(false);
@ -68,7 +70,7 @@ export const PenpotExporter = () => {
return ( return (
<main> <main>
<header> <header>
<img src={require('./logo.svg')} /> <Logo />
<h2>Penpot Exporter</h2> <h2>Penpot Exporter</h2>
</header> </header>
<section> <section>

View file

@ -1,7 +1,8 @@
import { PenpotFile } from '@ui/lib/penpot'; import { PenpotFile } from '@ui/lib/penpot';
import { CIRCLE_TYPE } from '@ui/lib/types/circle/circleAttributes'; import { CIRCLE_TYPE } from '@ui/lib/types/circle/circleAttributes';
import { CircleShape } from '@ui/lib/types/circle/circleShape'; import { CircleShape } from '@ui/lib/types/circle/circleShape';
import { translateFillGradients } from '@ui/translators';
import { translateFillGradients } from '../translators';
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
export const createPenpotCircle = (file: PenpotFile, { type, fills, ...rest }: CircleShape) => { export const createPenpotCircle = (file: PenpotFile, { type, fills, ...rest }: CircleShape) => {

12
ui-src/index.html Normal file
View file

@ -0,0 +1,12 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Penpot Exporter</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="./main.tsx"></script>
</body>
</html>

View file

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View file

@ -86,6 +86,8 @@ input:focus-visible {
svg { svg {
stroke: var(--color-icon, rgb(0 0 0 / 90%)); stroke: var(--color-icon, rgb(0 0 0 / 90%));
height: auto;
width: 2rem;
} }
main { main {
@ -111,11 +113,6 @@ footer > * + * {
margin-left: 0.5rem; margin-left: 0.5rem;
} }
img {
height: auto;
width: 2rem;
}
.missing-fonts small { .missing-fonts small {
font-size: 0.5rem; font-size: 0.5rem;
padding-top: 5px; padding-top: 5px;

View file

@ -2,9 +2,9 @@ import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client'; import { createRoot } from 'react-dom/client';
import { PenpotExporter } from './PenpotExporter'; import { PenpotExporter } from './PenpotExporter';
import './ui.css'; import './main.css';
createRoot(document.getElementById('penpot-export-page') as HTMLElement).render( createRoot(document.getElementById('root') as HTMLElement).render(
<StrictMode> <StrictMode>
<PenpotExporter /> <PenpotExporter />
</StrictMode> </StrictMode>

21
ui-src/tsconfig.json Normal file
View file

@ -0,0 +1,21 @@
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": false,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"typeRoots": ["../node_modules/@figma"]
}
}

2
ui-src/vite-env.d.ts vendored Normal file
View file

@ -0,0 +1,2 @@
/// <reference types="vite/client" />
/// <reference types="vite-plugin-svgr/client" />

22
vite.config.ts Normal file
View file

@ -0,0 +1,22 @@
import react from '@vitejs/plugin-react-swc';
import { defineConfig } from 'vite';
import { viteSingleFile } from 'vite-plugin-singlefile';
import svgr from 'vite-plugin-svgr';
import tsconfigPaths from 'vite-tsconfig-paths';
export default defineConfig({
root: './ui-src',
plugins: [svgr(), react(), viteSingleFile(), tsconfigPaths()],
build: {
target: 'esnext',
assetsInlineLimit: 100000000,
chunkSizeWarningLimit: 100000000,
cssCodeSplit: false,
outDir: '../dist',
rollupOptions: {
output: {
inlineDynamicImports: true
}
}
}
});

View file

@ -1,68 +0,0 @@
/* eslint-disable @typescript-eslint/no-var-requires */
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');
const webpack = require('webpack');
module.exports = (env, argv) => ({
mode: argv.mode === 'production' ? 'production' : 'development',
// This is necessary because Figma's 'eval' works differently than normal eval
devtool: argv.mode === 'production' ? false : 'inline-source-map',
entry: {
ui: './src/ui/ui.tsx', // The entry point for your UI code
code: './src/plugin/code.ts' // The entry point for your plugin code
},
module: {
rules: [
// Converts TypeScript code to JavaScript
{
test: /\.tsx?$/,
use: 'ts-loader',
exclude: /node_modules/
},
// Enables including CSS by doing "import './file.css'" in your TypeScript code
{
test: /\.css$/,
use: ['style-loader', 'css-loader']
},
// Allows you to use "<%= require('./file.svg') %>" in your HTML code to get a data URI
// { test: /\.(png|jpg|gif|webp|svg|zip)$/, loader: [{ loader: 'url-loader' }] }
{
test: /\.svg/,
type: 'asset/inline'
}
]
},
// Webpack tries these extensions for you if you omit the extension like "import './file'"
resolve: {
extensions: ['.tsx', '.ts', '.jsx', '.js'],
fallback: { crypto: false },
plugins: [new TsconfigPathsPlugin()]
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist') // Compile into a folder called "dist"
},
// Tells Webpack to generate "ui.html" and to inline "ui.ts" into it
plugins: [
new webpack.DefinePlugin({
global: {} // Fix missing symbol error when running in developer VM
}),
new HtmlWebpackPlugin({
inject: 'body',
template: './src/ui/ui.html',
filename: 'ui.html',
chunks: ['ui']
}),
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/ui/])
]
});