1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      怎么使用Vue3開發(fā)Fimga插件

      本篇內(nèi)容介紹了“怎么使用Vue3開發(fā)Fimga插件”的有關(guān)知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領(lǐng)大家學(xué)習(xí)一下如何處理這些情況吧!希望大家仔細閱讀,能夠?qū)W有所成!

      成都創(chuàng)新互聯(lián)成都企業(yè)網(wǎng)站建設(shè)服務(wù),提供網(wǎng)站設(shè)計制作、做網(wǎng)站網(wǎng)站開發(fā),網(wǎng)站定制,建網(wǎng)站,網(wǎng)站搭建,網(wǎng)站設(shè)計,響應(yīng)式網(wǎng)站建設(shè),網(wǎng)頁設(shè)計師打造企業(yè)風(fēng)格網(wǎng)站,提供周到的售前咨詢和貼心的售后服務(wù)。歡迎咨詢做網(wǎng)站需要多少錢:18982081108

      怎么使用Vue3開發(fā)Fimga插件

      用 Vue 3 開發(fā) Figma 插件

      Figma 是一款當(dāng)下流行的設(shè)計工具,越來越多的設(shè)計團隊開始從 Sketch 轉(zhuǎn)向 Figma。Figma 最大的特點是使用Web技術(shù)開發(fā),實現(xiàn)了完全的跨平臺。 Figma 插件也是使用 Web 技術(shù)開發(fā),只要會  htmljscss 就能動手寫一個 Figma 插件。

      Figma 插件原理

      Figma 架構(gòu)簡介

      介紹 Fimga 插件之前,我們先來了解一下 Fimga 的技術(shù)架構(gòu)。

      Figma 整體是用 React 開發(fā)的,核心的畫布區(qū)是一塊 canvas ,使用WebGL來渲染。并且畫布引擎部分使用的是WebAssembly,這就是 Figma 能夠如此流暢的原因。桌面端的Figma App 使用了 Electron——一個使用Web技術(shù)開發(fā)桌面應(yīng)用的框架。Electron 類似于一個瀏覽器,內(nèi)部運行的其實還是一個Web應(yīng)用。

      Figma 插件原理

      在Web端開發(fā)一套安全、可靠的插件系統(tǒng), iframe 無疑是最直接的方案。 iframe 是標準的W3C規(guī)范,在瀏覽器上已經(jīng)經(jīng)過多年應(yīng)用,它的特點是:

      • 安全,天然沙箱隔離環(huán)境,iframe內(nèi)頁面無法操作主框架;

      • 可靠,兼容性非常好,且經(jīng)過了多年市場的檢驗;

      但是它也有明顯的缺點:與主框架通信只能通過 postMessage(STRING) 的方式,通信效率非常低。如果要在插件里操作一個畫布元素,首先要將元素的節(jié)點信息從主框架拷貝到 iframe 中,然后在  iframe 中操作完再更新節(jié)點信息給主框架。這涉及到大量通信,而且對于復(fù)雜的設(shè)計稿節(jié)點信息是非常巨大的,可能超過通信的限制。

      為了保證操作畫布的能力,必須回到主線程。插件在主線程運行的問題主要在于安全性上,于是Figma的開發(fā)人員在主線程實現(xiàn)了一個 js 沙箱環(huán)境,使用了Realm API。沙箱中只能運行純粹的 js 代碼和Figma提供的API,無法訪問瀏覽器API(例如網(wǎng)絡(luò)、存儲等),這樣就保證了安全性。

      怎么使用Vue3開發(fā)Fimga插件

      感興趣的同學(xué)推薦閱讀官方團隊寫的《How to build a plugin system on the web and also sleep well at night》,詳細介紹了 Figma 插件方案的選擇過程,讀來獲益良多。

      經(jīng)過綜合考慮,F(xiàn)igma 將插件分成兩個部分:插件UI運行在 iframe 中,操作畫布的代碼運行在主線程的隔離沙箱中。UI線程和主線程通過  postMessage 通信。

      插件配置文件 manifest.json 中分別配置 main 字段指向加載到主線程的 js 文件, ui 字段配置加載到 iframe 中的 html 文件。打開插件時,主線程調(diào)用 figma.showUI() 方法加載 iframe

      寫一個最簡單的 Figma 插件

      為了了解插件的運行過程,我們先寫一個最簡單的 Figma 插件。功能很簡單:可以加減正方形色塊。

      安裝Figma桌面端

      首先要下載并安裝好 Figma 桌面端。

      編寫插件的啟動文件 manifest.json

      新建一個代碼工程,在根目錄中新建 manifest.json 文件,內(nèi)容如下:

      {
        "name": "simple-demo",
        "api": "1.0.0",
        "main": "main.js",
        "ui": "index.html",
        "editorType": [
          "figjam",
          "figma"
        ]
      }
      編寫UI代碼

      根目錄新建 index.html

      
      
      
        
        
        
        Demo
        
       
      
      
        

      Figma 插件 Demo

        

      當(dāng)前色塊數(shù)量:0

        
          +     -   
        
      編輯main js 代碼

      根目錄新建 main.js ,內(nèi)容如下:

      console.log('from code 2');
      figma.showUI(__html__, {
        width: 400,
        height: 400,
      });
      啟動插件

      Figma桌面APP,畫布任意地方右鍵打開菜單, Plugins -> Development -> Import plugin from manifest... ,選擇前面創(chuàng)建的 manifest.json 文件路徑,即可成功導(dǎo)入插件。 然后通過右鍵, Plugins -> Development -> simple-demo (插件名),就可以打開插件。

      怎么使用Vue3開發(fā)Fimga插件

      測試點擊按鈕,功能正常。只不過頁面上還未出現(xiàn)色塊(別著急)。 通過 Plugins -> Development -> Open console  可以打開調(diào)試控制臺。可以看到我們打印的日志。

      操作畫布

      前面講了,畫布代碼是運行在主線程的,為了執(zhí)行效率,插件要操作畫布內(nèi)容也只能在主線程執(zhí)行,即在 main.js 中。 main.js 中暴露了頂級對象 figma ,封裝了用來操作畫布的一系列API,具體可以去看官網(wǎng)文檔。我們用 figma.createRectangle() 來創(chuàng)建一個矩形。主線程需要通過 figma.ui.onmessage 監(jiān)聽來自UI線程的事件,從而做出響應(yīng)。修改后的 main.js 代碼如下:

      console.log('figma plugin code runs!')
      
      figma.showUI(__html__, {
        width: 400,
        height: 400,
      });
      
      const nodes = [];
      
      figma.ui.onmessage = (msg) => {=
        if (msg.type === "add-block") {
          const rect = figma.createRectangle();
          rect.x = nodes.length * 150;
          rect.fills = [{ type: "SOLID", color: { r: 1, g: 0.5, b: 0 } }];
          figma.currentPage.appendChild(rect);
          nodes.push(rect);
        } else if (msg.type === "sub-block") {
          const rect = nodes.pop();
          if (rect) {
            rect.remove();
          }
        }
        figma.viewport.scrollAndZoomIntoView(nodes);
      };

      同時要修改  index.html 中的部分代碼,通過 parent.postMessage 給主線程發(fā)送事件:

      function addBlock() {
        console.log('add');
        var num = +blockNumEle.innerText;
        num += 1;
        blockNumEle.innerText = num;
        parent.postMessage({ pluginMessage: { type: 'add-block' } }, '*')
      }
      
      function subBlock() {
        console.log('substract');
        var num = +blockNumEle.innerText;
        if (num === 0) return;
        num -= 1;
        blockNumEle.innerText = num;
        parent.postMessage({ pluginMessage: { type: 'sub-block' } }, '*')
      }

      重新啟動插件,再試驗一下,發(fā)現(xiàn)已經(jīng)可以成功加減色塊了。

      怎么使用Vue3開發(fā)Fimga插件

      使用 Vue 3 開發(fā) Figma 插件

      通過前面的例子,我們已經(jīng)清楚 Figma 插件的運行原理。但是用這種“原生”的 jshtml 來編寫代碼非常低效的。我們完全可以用最新的Web技術(shù)來編寫代碼,只要打包產(chǎn)物包括一個運行在主框架的 js 文件和一個給 iframe 運行的 html 文件即可。我決定嘗試使用  Vue 3 來開發(fā)插件。(學(xué)習(xí)視頻分享:vuejs教程)

      關(guān)于 Vue 3 就不多做介紹了,懂的都懂,不懂的看到這里可以先去學(xué)習(xí)一下再來。這里的重點不在于用什么框架(改成用vue 2、react過程也差不多),而在于構(gòu)建工具。

      Vite 啟動一個新項目

      Vite 是Vue的作者開發(fā)的新一代構(gòu)建工具,也是 Vue 3推薦的構(gòu)建工具。 我們先建一個 Vue  +  TypeScript 的模板項目。

      npm init vite@latest figma-plugin-vue3 --template vue-ts
      cd figma-plugin-vue3
      npm install
      npm run dev

      然后通過瀏覽器打開 http://localhost:3000 就能看到頁面。

      移植上述demo代碼

      我們把前面的插件demo移植到 Vue 3 中。 src/App.vue 代碼修改如下:

      
      
      
      
      h2 {
        text-align: center;
      }
      p {
        color: red;
      }
      
      .buttons {
        margin-top: 20px;
        text-align: center;
      }
      
      .buttons button {
        width: 40px;
      }
      
      #block-num {
        font-size: 20px;
      }
      

      我們在 src/worker 目錄存放運行在主線程沙箱中的js代碼。新建 src/worker/code.ts ,內(nèi)容如下:

      console.log('figma plugin code runs!')
      
      figma.showUI(__html__, {
        width: 400,
        height: 400,
      });
      
      const nodes: RectangleNode[] = [];
      
      figma.ui.onmessage = (msg) => {
        
        if (msg.type === "add-block") {
          const rect = figma.createRectangle();
          rect.x = nodes.length * 150;
          rect.fills = [{ type: "SOLID", color: { r: 1, g: 0.5, b: 0 } }];
          figma.currentPage.appendChild(rect);
          nodes.push(rect);
        } else if (msg.type === "sub-block") {
          const rect = nodes.pop();
          if (rect) {
            rect.remove();
          }
        }
      
        figma.viewport.scrollAndZoomIntoView(nodes);
      
      };

      上述代碼中缺少 figma 的 ts 類型聲明,所以我們需要安裝一下。

      npm i -D @figma/plugin-typings

      修改 tsconfig.json ,添加 typeRoots ,這樣 ts 代碼就不會報錯了。同時也要加上 "skipLibCheck": true ,解決類型聲明沖突問題。

      {
        "compilerOptions": {
          // ...
      "skipLibCheck": true,
          "typeRoots": [
            "./node_modules/@types",
            "./node_modules/@figma"
          ]
        },
      }

      修改構(gòu)建配置

      Figma 插件需要的構(gòu)建產(chǎn)物有:

      • manifest.json  文件作為插件配置

      • index.html 作為UI代碼

      • code.js 作為主線程js代碼

      在 public 目錄中添加 manifest.json 文件

      public 目錄中的文件都會負責(zé)到構(gòu)建產(chǎn)物 dist 目錄下。

      {
        "name": "figma-plugin-vue3",
        "api": "1.0.0",
        "main": "code.js",
        "ui": "index.html",
        "editorType": [
          "figjam",
          "figma"
        ]
      }
      vite.config.ts  中增加構(gòu)建入口

      默認情況下 vite 會用 index.html 作為構(gòu)建入口,里面用到的資源會被打包構(gòu)建。我們還需要一個入口,用來構(gòu)建主線程 js 代碼。

      執(zhí)行  npm i -D @types/node ,安裝  Node.js  的類型聲明,以便在 ts 中使用  Node.js  API。 vite.config.ts  的  build.rollupOptions  中增加  input 。默認情況下輸出產(chǎn)物會帶上文件 hash ,所以也要修改 output 配置:

      import { defineConfig } from 'vite'
      import vue from '@vitejs/plugin-vue'
      import { resolve } from 'path';
      
      // https://vitejs.dev/config/
      export default defineConfig({
        plugins: [vue()],
        build: {
          sourcemap: 'inline',
          rollupOptions: {
            input:{
                  main: resolve(__dirname, 'index.html'),
                  code: resolve(__dirname, 'src/worker/code.ts'),
                },
            output: {
              entryFileNames: '[name].js',
            },
          },
        },
      })
      運行構(gòu)建

      執(zhí)行 npm run builddist 目錄會有構(gòu)建產(chǎn)物。然后我們按照前面的步驟,將  dist  目錄添加為 Figma 插件。 Plugins -> Development -> Import plugin from manifest... ,選擇 dist/manifest.json 文件路徑。

      啟動插件......怎么插件里一片空白?好在 Figma 里面有 devtools 調(diào)試工具,我們打開瞧一瞧。

      怎么使用Vue3開發(fā)Fimga插件

      可以看到,我們的 index.html 已經(jīng)成功加載,但是 js 代碼沒加載所以頁面空白。js、css 等資源是通過相對路徑引用的,而我們的 iframe 中的 src 是一個 base64 格式內(nèi)容,在尋找 js 資源的時候因為沒有域名,所以找不到資源。

      解決辦法也很簡單,我們給資源加上域名,然后本地起一個靜態(tài)資源服務(wù)器就行了。修改  vite.config.ts ,加上 base: 'http://127.0.0.1:3000'

      import { defineConfig } from 'vite'
      import vue from '@vitejs/plugin-vue'
      import { resolve } from 'path';
      
      // https://vitejs.dev/config/
      export default defineConfig({
        plugins: [vue()],
        base: 'http://127.0.0.1:3000',
        build: {
          sourcemap: 'inline',
          rollupOptions: {
            input: {
              main: resolve(__dirname, 'index.html'),
              code: resolve(__dirname, 'src/worker/code.ts'),
            },
            output: {
              entryFileNames: '[name].js',
            },
          },
        },
        preview: {
          port: 3000,
        },
      })

      重新構(gòu)建代碼 npm run build 。然后啟動靜態(tài)資源服務(wù)器 npm run preview 。通過瀏覽器訪問 http://localhost:3000/ 可以看到內(nèi)容。

      然后重新打開 Figma 插件看看。果然,插件已經(jīng)正常了!

      怎么使用Vue3開發(fā)Fimga插件

      Figma 加載插件只需要  index.html  和  code.js ,其他資源都可以通過網(wǎng)絡(luò)加載。這意味著我們可以將 js、css 資源放在服務(wù)端,實現(xiàn)插件的熱更?不知道發(fā)布插件的時候會不會有限制,這個我還沒試過。

      開發(fā)模式

      我們已經(jīng)能成功通過 Vue 3 來構(gòu)建 Figma 插件了,但是我不想每次修改代碼都要構(gòu)建一遍,我們需要能夠自動構(gòu)建代碼的開發(fā)模式。

      vite 自動的 dev模式是啟動了一個服務(wù),沒有構(gòu)建產(chǎn)物(而且沒有類似webpack里面的  writeToDisk 配置),所以無法使用。

      watch 模式

      vite 的 build 命令有watch模式,可以監(jiān)聽文件改動然后自動執(zhí)行  build 。我們只需要修改 package.jsonscripts  里新增  "watch": "vite build --watch"

      npm run watch
      
      # 同時要在另一個終端里啟動靜態(tài)文件服務(wù)
      npm run preview

      這種方式雖然修改代碼后會自動編譯,但是每次還是要關(guān)閉插件并重新打開才能看到更新。這樣寫UI還是太低效了,能不能在插件里實現(xiàn)  HMR  (模塊熱重載)功能呢?

      dev 模式

      vite dev 的問題在于沒有構(gòu)建產(chǎn)物。 code.js  是運行在 Fimga 主線程沙箱中的,這部分是無法熱重載的,所以可以利用 vite build --watch 實現(xiàn)來編譯。需要熱重載的是 index.html  以及相應(yīng)的 js 、css 資源。 先來看一下 npm run dev 模式下的 html 資源有什么內(nèi)容:

      怎么使用Vue3開發(fā)Fimga插件

      理論上來說,我們只需要把這個 html 手動寫入到  dist  目錄就行,熱重載的時候 html 文件不需要修改。直接寫入的話會遇到資源是相對路徑的問題,所以要么把資源路徑都加上域名( http://localhost:3000 ),或者使用 標簽。

      手動生成 html 文件

      對比上面的 html 代碼和根目錄的 index.html  文件,發(fā)現(xiàn)只是增加了一個 。所以我們可以自己解析  index.html ,然后插入相應(yīng)這個標簽,以及一個   標簽。解析 HTML 我們用  jsdom  。

      const JSDOM = require('jsdom');
      const fs = require('fs');
      
      // 生成 html 文件
      function genIndexHtml(sourceHTMLPath, targetHTMLPath) {
        const htmlContent = fs.readFileSync(sourceHTMLPath, 'utf-8');
        const dom = new JSDOM(htmlContent);
        const { document } = dom.window;
        
        const script = document.createElement('script');
        script.setAttribute('type', 'module');
        script.setAttribute('src', '/@vite/client');
        dom.window.document.head.insertBefore(script, document.head.firstChild);
        
        const base = document.createElement('base');
        base.setAttribute('href', 'http://127.0.0.1:3000/');
        dom.window.document.head.insertBefore(base, document.head.firstChild);
      
        const result = dom.serialize();
        fs.writeFileSync(targetHTMLPath, result);
      }

      同時 vite 提供了 JavaScript API,所以我們可以代碼組織起來,寫一個 js 腳本來啟動開發(fā)模式。新建文件 scripts/dev.js ,完整內(nèi)容如下:

      const { JSDOM } = require('jsdom');
      const fs = require('fs');
      const path = require('path');
      const vite = require('vite');
      
      const rootDir = path.resolve(__dirname, '../');
      
      function dev() {
        const htmlPath = path.resolve(rootDir, 'index.html');
        const targetHTMLPath = path.resolve(rootDir, 'dist/index.html');
        genIndexHtml(htmlPath, targetHTMLPath);
      
        buildMainCode();
      
        startDevServer();
      }
      
      // 生成 html 文件
      function genIndexHtml(sourceHTMLPath, targetHTMLPath) {
        const htmlContent = fs.readFileSync(sourceHTMLPath, 'utf-8');
        const dom = new JSDOM(htmlContent);
        const {
          document
        } = dom.window;
      
        const script = document.createElement('script');
        script.setAttribute('type', 'module');
        script.setAttribute('src', '/@vite/client');
        dom.window.document.head.insertBefore(script, document.head.firstChild);
      
        const base = document.createElement('base');
        base.setAttribute('href', 'http://127.0.0.1:3000/');
        dom.window.document.head.insertBefore(base, document.head.firstChild);
      
        const result = dom.serialize();
        fs.writeFileSync(targetHTMLPath, result);
      }
      
      // 構(gòu)建 code.js 入口
      async function buildMainCode() {
        const config = vite.defineConfig({
          configFile: false, // 關(guān)閉默認使用的配置文件
          build: {
            emptyOutDir: false, // 不要清空 dist 目錄
            lib: { // 使用庫模式構(gòu)建
              entry: path.resolve(rootDir, 'src/worker/code.ts'),
              name: 'code',
              formats: ['es'],
              fileName: (format) => `code.js`,
            },
            sourcemap: 'inline',
            watch: {},
          },
        });
        return vite.build(config);
      }
      
      // 開啟 devServer
      async function startDevServer() {
        const config = vite.defineConfig({
          configFile: path.resolve(rootDir, 'vite.config.ts'),
          root: rootDir,
          server: {
            hmr: {
              host: '127.0.0.1', // 必須加上這個,否則 HMR 會報錯
            },
            port: 3000,
          },
          build: {
            emptyOutDir: false, // 不要清空 dist 目錄
            watch: {}, // 使用 watch 模式
          }
        });
        const server = await vite.createServer(config);
        await server.listen()
      
        server.printUrls()
      }
      
      dev();

      執(zhí)行  node scripts/dev.js ,然后在 Figma 中重啟插件。試試修改一下 Vue 代碼,發(fā)現(xiàn)插件內(nèi)容自動更新了!

      怎么使用Vue3開發(fā)Fimga插件

      最后在  package.json  中新建一個修改一下dev的內(nèi)容為 "dev": "node scripts/dev.js" 就可以了。

      通過請求來獲取 HTML

      前面通過自己生產(chǎn)  index.html  的方式有很大的弊端:萬一后續(xù) vite 更新后修改了默認 html 的內(nèi)容,那我們的腳本也要跟著修改。有沒有更健壯的方式呢?我想到可以通過請求 devServer 來獲取 html 內(nèi)容,然后寫入本地。話不多說,修改后代碼如下:

      const { JSDOM } = require('jsdom');
      const fs = require('fs');
      const path = require('path');
      const vite = require('vite');
      const axios = require('axios');
      
      const rootDir = path.resolve(__dirname, '../');
      
      async function dev() {
        // const htmlPath = path.resolve(rootDir, 'index.html');
        const targetHTMLPath = path.resolve(rootDir, 'dist/index.html');
      
        await buildMainCode();
      
        await startDevServer();
        
        // 必須放到 startDevServer 后面執(zhí)行
        await genIndexHtml(targetHTMLPath);
      }
      
      // 生成 html 文件
      async function genIndexHtml(/* sourceHTMLPath,*/ targetHTMLPath) {
        const htmlContent = await getHTMLfromDevServer();
        const dom = new JSDOM(htmlContent);
        
        // ...
      
        const result = dom.serialize();
        fs.writeFileSync(targetHTMLPath, result);
      }
      
      // ...
      
      // 通過請求 devServer 獲取HTML
      async function getHTMLfromDevServer () {
        const rsp = await axios.get('http://localhost:3000/index.html');
        return rsp.data;
      }
      
      dev();

      “怎么使用Vue3開發(fā)Fimga插件”的內(nèi)容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業(yè)相關(guān)的知識可以關(guān)注創(chuàng)新互聯(lián)網(wǎng)站,小編將為大家輸出更多高質(zhì)量的實用文章!


      本文標題:怎么使用Vue3開發(fā)Fimga插件
      網(wǎng)址分享:http://www.ef60e0e.cn/article/pedgph.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        扶绥县| 双牌县| 隆子县| 兖州市| 电白县| 兰溪市| 马鞍山市| 延寿县| 丽江市| 莲花县| 榆树市| 博客| 云林县| 鱼台县| 宝兴县| 西宁市| 桑日县| 花莲县| 西乌| 浦城县| 三原县| 虹口区| 宣汉县| 彰化县| 辽中县| 富民县| 颍上县| 桐庐县| 普陀区| 确山县| 滕州市| 石门县| 北票市| 东明县| 拜泉县| 利津县| 武宣县| 德江县| 大理市| 苍溪县| 彩票|