├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── workflows │ └── codeql-analysis.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── assets ├── awesome-rsw.svg ├── fzj-qrcode.png └── wasm-qrcode.png ├── package.json ├── pnpm-workspace.yaml ├── src ├── index.ts ├── rswerr.ts ├── template.ts └── watch.ts └── tsconfig.json /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | open_collective: vite-plugin-rsw 2 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: "" 5 | labels: bug 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Additional context** 32 | Add any other context about the problem here. 33 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: "" 5 | labels: feat 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/workflows/codeql-analysis.yml: -------------------------------------------------------------------------------- 1 | # For most projects, this workflow file will not need changing; you simply need 2 | # to commit it to your repository. 3 | # 4 | # You may wish to alter this file to override the set of languages analyzed, 5 | # or to provide custom queries or build logic. 6 | # 7 | # ******** NOTE ******** 8 | # We have attempted to detect the languages in your repository. Please check 9 | # the `language` matrix defined below to confirm you have the correct set of 10 | # supported CodeQL languages. 11 | # 12 | name: "CodeQL" 13 | 14 | on: 15 | push: 16 | branches: [ main ] 17 | pull_request: 18 | # The branches below must be a subset of the branches above 19 | branches: [ main ] 20 | schedule: 21 | - cron: '15 9 * * 4' 22 | 23 | jobs: 24 | analyze: 25 | name: Analyze 26 | runs-on: ubuntu-latest 27 | 28 | strategy: 29 | fail-fast: false 30 | matrix: 31 | language: [ 'javascript' ] 32 | # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python' ] 33 | # Learn more: 34 | # https://docs.github.com/en/free-pro-team@latest/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#changing-the-languages-that-are-analyzed 35 | 36 | steps: 37 | - name: Checkout repository 38 | uses: actions/checkout@v2 39 | 40 | # Initializes the CodeQL tools for scanning. 41 | - name: Initialize CodeQL 42 | uses: github/codeql-action/init@v1 43 | with: 44 | languages: ${{ matrix.language }} 45 | # If you wish to specify custom queries, you can do so here or in a config file. 46 | # By default, queries listed here will override any specified in a config file. 47 | # Prefix the list here with "+" to use these queries and those in the config file. 48 | # queries: ./path/to/local/query, your-org/your-repo/queries@main 49 | 50 | # Autobuild attempts to build any compiled languages (C/C++, C#, or Java). 51 | # If this step fails, then you should remove it and run the build manually (see below) 52 | - name: Autobuild 53 | uses: github/codeql-action/autobuild@v1 54 | 55 | # ℹ️ Command-line programs to run using the OS shell. 56 | # 📚 https://git.io/JvXDl 57 | 58 | # ✏️ If the Autobuild fails above, remove it and uncomment the following three lines 59 | # and modify them (or add more) to build your code if your project 60 | # uses a compiled language 61 | 62 | #- run: | 63 | # make bootstrap 64 | # make release 65 | 66 | - name: Perform CodeQL Analysis 67 | uses: github/codeql-action/analyze@v1 68 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .history 3 | 4 | dist/ 5 | node_modules 6 | *.log 7 | package-lock.json 8 | 9 | pnpm-lock.yaml 10 | *.lock 11 | 12 | # rust 13 | target/ -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 2.0.8 (2022-06-27) 2 | 3 | - fix: reload 4 | ## 2.0.0 (2022-02-27) 5 | 6 | - a major upgrade based on `rsw-rs` 7 | 8 | ## 1.10.0 (2021-10-02) 9 | 10 | ### feature 11 | 12 | - [Add plugin options](https://github.com/lencx/vite-plugin-rsw/issues/22) 13 | 14 | ## 1.9.1 (2021-08-24) 15 | 16 | ### fix 17 | 18 | - [Whitespaces in project path do not work](https://github.com/lencx/vite-plugin-rsw/issues/20) 19 | 20 | ## 1.9.0 (2021-08-22) 21 | 22 | - [Watch for dependent workspace crates](https://github.com/lencx/vite-plugin-rsw/issues/18) 23 | - [Automatically generate .rsw.json](https://github.com/lencx/vite-plugin-rsw/issues/19) 24 | 25 | ## 1.8.0 (2021-07-13) 26 | 27 | - remove replace: Vite v2.4.x support new URL(url, import.meta.url) 28 | 29 | ## 1.7.0 (2021-07-09) 30 | 31 | - [x] rsw options 32 | - cli 33 | - root 34 | - unLinks 35 | - crates 36 | - [x] startup optimization 37 | - [x] enable debug mode 38 | - [x] friendly error message 39 | - [x] automatically generate template 40 | - [x] multiple rust crate 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 lencx 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # vite-plugin-rsw 2 | 3 | > wasm-pack plugin for Vite 4 | 5 | [![npm](https://img.shields.io/npm/v/vite-plugin-rsw.svg)](https://www.npmjs.com/package/vite-plugin-rsw) 6 | [![npm downloads](https://img.shields.io/npm/dm/vite-plugin-rsw.svg)](https://npmjs.org/package/vite-plugin-rsw) 7 | [![vite version](https://img.shields.io/badge/Vite-^2.0.0-000000?style=flat&labelColor=646cff)](https://github.com/vitejs/vite) 8 | [![chat](https://img.shields.io/badge/chat-discord-blue?style=flat&logo=discord)](https://discord.gg/euyYWXTwmk) 9 | 10 | [![awesome-rsw](./assets/awesome-rsw.svg)](https://github.com/lencx/awesome-rsw) 11 | [![Rust](https://img.shields.io/badge/-Rust-DEA584?style=flat&logo=rust&logoColor=000000)](https://www.rust-lang.org) 12 | [![WebAssembly](https://img.shields.io/badge/-WebAssembly-654FF0?style=flat&logo=webassembly&logoColor=ffffff)](https://webassembly.org) 13 | 14 | |rsw version|vite version| 15 | |---|---| 16 | | >= `2.0.0`| >= `2.8.0`| 17 | | >= `1.8.0`| >= `2.4.0`| 18 | |`1.7.0`|`2.0.0 ~ 2.3.8`| 19 | 20 | ## Features 21 | 22 | - `HMR` 23 | - `Friendly error message` - browser and terminal 24 | 25 | ## Pre-installed 26 | 27 | - [rust](https://www.rust-lang.org/learn/get-started) 28 | - [nodejs](https://nodejs.org) 29 | - [wasm-pack](https://github.com/rustwasm/wasm-pack) 30 | - [rsw-rs](https://github.com/lencx/rsw-rs): `rsw = rs(rust) → w(wasm)` - A command-line tool for automatically rebuilding local changes, based on the wasm-pack implementation. 31 | 32 | ## Usage 33 | 34 | ### Step 1 35 | 36 | Install rsw 37 | 38 | ```bash 39 | cargo install rsw 40 | ``` 41 | 42 | Install vite-plugin-rsw 43 | 44 | ```bash 45 | # With NPM: 46 | npm i -D vite-plugin-rsw 47 | 48 | # With Yarn: 49 | yarn add -D vite-plugin-rsw 50 | ``` 51 | 52 | ### Step 2 53 | 54 | Edit vite.config.ts 55 | 56 | ```js 57 | import { defineConfig } from 'vite'; 58 | import { ViteRsw } from 'vite-plugin-rsw'; 59 | 60 | export default defineConfig({ 61 | plugins: [ 62 | ViteRsw(), 63 | ], 64 | }) 65 | ``` 66 | 67 | ### Step 3 68 | 69 | Edit package.json 70 | > recommend to use `concurrently` instead of `&` to run command concurrently, because it can't handle system signal properly, see https://github.com/rwasm/rsw-rs/issues/7 71 | ```json5 72 | "scripts": { 73 | + "dev": "concurrently \"rsw watch\" \"vite\"", 74 | + "build": "rsw build && tsc && vite build", 75 | + "rsw": "rsw" 76 | } 77 | ``` 78 | 79 | ### Step 4 80 | 81 | [rsw.toml options](https://github.com/rwasm/rsw-rs#options) 82 | 83 | 1. Initial rsw.toml 84 | 85 | ```bash 86 | # yarn rsw -h 87 | yarn rsw init 88 | ``` 89 | 90 | 2. Generate rust crate 91 | 92 | ```bash 93 | # rsw.toml 94 | [new] 95 | # using: wasm-pack | rsw | user, default is `wasm-pack` 96 | using = "wasm-pack" 97 | ``` 98 | 99 | ```bash 100 | yarn rsw new rsw-hello 101 | ``` 102 | 103 | 3. Edit rsw.toml 104 | 105 | ```toml 106 | # link type: npm | yarn | pnpm, default is `npm` 107 | cli = "npm" 108 | 109 | [[crates]] 110 | name = "rsw-hello" 111 | # link 112 | # ⚠️ Note: must be set to `true`, default is `false` 113 | link = true 114 | ``` 115 | 116 | ### Step 5 117 | 118 | Start dev server 119 | 120 | ```bash 121 | # rsw watch & vite 122 | yarn dev 123 | ``` 124 | 125 | ### Step 6 126 | 127 | Deploy 128 | 129 | ```bash 130 | yarn build 131 | ``` 132 | 133 | ### Example 134 | 135 | - [WA+](https://github.com/lencx/WA) - 🤩 Making a web page more like a desktop application is just the beginning, the possibilities are unlimited, up to your imagination! 136 | - [Demo](https://github.com/lencx/learn-wasm) - 🎲 Learning WebAssembly 137 | - [Oh My Box](https://github.com/lencx/OhMyBox) - 🔮 Development toolbox, and more... 138 | 139 | ## Related 140 | 141 | [create-mpl](https://github.com/lencx/create-mpl) - ⚡️ Create a project in seconds! 142 | 143 | ```bash 144 | # Quickly initialize a wasm project 145 | 146 | # npm 6.x 147 | npm init mpl@latest my-app --type wasm 148 | 149 | # npm 7+, extra double-dash is needed: 150 | npm init mpl@latest my-app -- --type wasm 151 | ``` 152 | 153 | --- 154 | 155 | ## 微信 156 | 157 | > 群二维码已过期,关注公众号《浮之静》,发送“进群”,我将拉你进群一起学习。 158 | 159 | wasm-wechat-qrcode fzj-qrcode 160 | 161 | ## License 162 | 163 | MIT License © 2021 [lencx](https://github.com/lencx) 164 | -------------------------------------------------------------------------------- /assets/awesome-rsw.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /assets/fzj-qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwasm/vite-plugin-rsw/a108244b4a4b458c7a1f2de5585816ca330d6fdf/assets/fzj-qrcode.png -------------------------------------------------------------------------------- /assets/wasm-qrcode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rwasm/vite-plugin-rsw/a108244b4a4b458c7a1f2de5585816ca330d6fdf/assets/wasm-qrcode.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vite-plugin-rsw", 3 | "description": "wasm-pack plugin for Vite", 4 | "version": "2.0.11", 5 | "author": "lencx ", 6 | "main": "dist/index.js", 7 | "module": "dist/index.mjs", 8 | "types": "dist/index.d.ts", 9 | "files": [ 10 | "dist" 11 | ], 12 | "scripts": { 13 | "dev": "npm run build -- --watch", 14 | "build": "tsup src/index.ts --dts --minify --format cjs,esm", 15 | "prepublishOnly": "npm run build", 16 | "release": "npx bumpp --push --tag --commit && npm publish" 17 | }, 18 | "repository": { 19 | "type": "git", 20 | "url": "https://github.com/lencx/vite-plugin-rsw" 21 | }, 22 | "homepage": "https://github.com/lencx/vite-plugin-rsw", 23 | "bugs": "https://github.com/lencx/vite-plugin-rsw/issues", 24 | "license": "MIT", 25 | "keywords": [ 26 | "rsw", 27 | "wasm", 28 | "vite", 29 | "plugin", 30 | "wasm-pack", 31 | "vite-plugin", 32 | "webAssembly" 33 | ], 34 | "peerDependencies": { 35 | "vite": ">2.8.0-0" 36 | }, 37 | "devDependencies": { 38 | "@antfu/eslint-config": "^0.16.1", 39 | "@types/node": "^17.0.21", 40 | "@types/which": "^2.0.1", 41 | "@typescript-eslint/eslint-plugin": "^5.12.1", 42 | "@typescript-eslint/parser": "^5.12.1", 43 | "eslint": "^8.9.0", 44 | "tsup": "^5.11.13", 45 | "typescript": "^4.5.5", 46 | "vite": "*" 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /pnpm-workspace.yaml: -------------------------------------------------------------------------------- 1 | packages: 2 | - examples/ -------------------------------------------------------------------------------- /src/index.ts: -------------------------------------------------------------------------------- 1 | import type { Plugin, ResolvedConfig } from 'vite'; 2 | 3 | import { watch, getCrates } from './watch'; 4 | import fmtRustError from './rswerr'; 5 | import { rswOverlay, rswHot } from './template'; 6 | 7 | const toUnixPath = (path: string) => path.replace(/[\\/]+/g, '/').replace(/^([a-zA-Z]+:|\.\/)/, ''); 8 | 9 | export function ViteRsw(): Plugin { 10 | let config: ResolvedConfig; 11 | 12 | const { cratesPath } = getCrates(); 13 | // const re1 = crates.join('|'); 14 | const re2 = cratesPath.map(i => `${i}/.*.js`).join('|'); 15 | 16 | return { 17 | name: 'vite-plugin-rsw', 18 | enforce: 'pre', 19 | apply: 'serve', 20 | configResolved(_config) { 21 | config = _config; 22 | }, 23 | handleHotUpdate({ file, server }) { 24 | let isInit = true; 25 | const _file = toUnixPath(file); 26 | if (/\/target(\/[\d\w-_]+)?\/debug\//.test(_file) || /\.rsw\//.test(_file)) return; 27 | if (/\.rs$/.test(_file)) { 28 | watch((opts) => { 29 | if (opts.status === 'ok') { 30 | server.ws.send({ 31 | type: 'full-reload', 32 | path: '*' 33 | }); 34 | } 35 | if (opts.status === 'err') { 36 | server.ws.send({ 37 | type: 'custom', 38 | event: 'rsw-error', 39 | data: { 40 | plugin: '[vite::rsw]', 41 | message: fmtRustError(opts.error), 42 | id: opts.path, 43 | console: opts.error, 44 | }, 45 | }); 46 | } 47 | }, isInit); 48 | } 49 | }, 50 | transform(code, id) { 51 | const _id = toUnixPath(id); 52 | if (new RegExp(`${re2}`).test(_id)) { 53 | return code + rswHot; 54 | } 55 | return code; 56 | }, 57 | transformIndexHtml(html) { 58 | // compiler error overlay 59 | if (config?.mode === 'development') { 60 | return [ 61 | { 62 | tag: 'script', 63 | attrs: { type: 'module' }, 64 | children: rswOverlay, 65 | }, 66 | ] 67 | } 68 | return html; 69 | }, 70 | }; 71 | } 72 | 73 | export default ViteRsw; 74 | -------------------------------------------------------------------------------- /src/rswerr.ts: -------------------------------------------------------------------------------- 1 | class RustError { 2 | // current line 3 | line: string; 4 | // current index 5 | index: number; 6 | // browser display 7 | msgTagGroup: string[]; 8 | 9 | constructor() { 10 | this.line = ''; 11 | this.index = -1; 12 | this.msgTagGroup = []; 13 | } 14 | 15 | init(line: string, index: number) { 16 | this.line = line; 17 | this.index= index; 18 | this.msgTagGroup[index] = line; 19 | return this; 20 | } 21 | 22 | setTag(type: string, reg: RegExp) { 23 | if (new RegExp(reg).test(this.line)) { 24 | this.msgTagGroup[this.index] = this.line.replace(reg, `$1`); 25 | } 26 | } 27 | 28 | handle(type: string, reg: RegExp) { 29 | this.setTag(type, reg); 30 | return this; 31 | } 32 | 33 | getValue() { 34 | return this.msgTagGroup.join('\n'); 35 | } 36 | } 37 | 38 | export default function fmtRustError(content: String) { 39 | const rsIns = new RustError(); 40 | /** 41 | * Compiling crate 42 | * --> 43 | * 2 | code error 44 | * 3 | ^^^^^ 45 | * = note: 46 | * warning: 47 | * error: 48 | * error[E0425]: 49 | * help: 50 | */ 51 | content.split('\n').forEach((line, index) => { 52 | rsIns.init(line, index) 53 | .handle('line', /(^\s+-->|\s*=|[\s\d]*\|)/) 54 | .handle('compiling', /(^\s+Compiling)/) 55 | .handle('error', /(^error(\[\w+\])?)/) 56 | .handle('warn', /(^warning)/) 57 | .handle('help', /(^help)/); 58 | }); 59 | 60 | return rsIns.getValue(); 61 | } 62 | -------------------------------------------------------------------------------- /src/template.ts: -------------------------------------------------------------------------------- 1 | export const rswHot = ` 2 | if (import.meta.hot) { 3 | import.meta.hot.on('rsw-error', (data) => { 4 | createRswErrorOverlay && createRswErrorOverlay(data); 5 | throw \`\n🦀\${data.plugin} ~> \${data.id}\n\n\${data.console}\` 6 | }) 7 | }`; 8 | 9 | export const rswOverlay = ` 10 | const rswTemplate = \` 11 | 107 |
108 | 109 |

110 |   

111 |   
112 | [rsw::error] This error occurred during the build time, click outside or fix the code to dismiss. 113 |
114 |
115 | \`; 116 | class RswErrorOverlay extends HTMLElement { 117 | constructor(payload) { 118 | super() 119 | this.root = this.attachShadow({ mode: 'open' }); 120 | this.root.innerHTML = rswTemplate; 121 | this.text('.message', payload.message.trim()); 122 | this.text('.plugin', payload.plugin.trim()); 123 | this.text('.file', payload.id.trim()); 124 | this.root.querySelector('.window').addEventListener('click', (e) => { 125 | e.stopPropagation(); 126 | }); 127 | this.addEventListener('click', () => { 128 | this.close(); 129 | }); 130 | } 131 | text(selector, text) { 132 | const el = this.root.querySelector(selector); 133 | if (el) el.innerHTML = text; 134 | } 135 | close() { 136 | if (this.parentNode) this.parentNode.removeChild(this); 137 | } 138 | } 139 | const overlayRswId = 'vite-rsw-error-overlay'; 140 | if (!customElements.get(overlayRswId)) { 141 | customElements.define(overlayRswId, RswErrorOverlay); 142 | } 143 | function createRswErrorOverlay(err) { 144 | clearRswErrorOverlay(); 145 | document.body.appendChild(new RswErrorOverlay(err)); 146 | } 147 | function clearRswErrorOverlay() { 148 | document 149 | .querySelectorAll(overlayRswId) 150 | .forEach((n) => n.close()); 151 | } 152 | window.createRswErrorOverlay = createRswErrorOverlay;`; 153 | -------------------------------------------------------------------------------- /src/watch.ts: -------------------------------------------------------------------------------- 1 | import fs from 'fs'; 2 | import path from 'path'; 3 | import readline from 'readline'; 4 | 5 | interface RswInfo { 6 | status: 'ok' | 'err' | ''; 7 | name: string; 8 | path: string; 9 | build: string; 10 | error: string; 11 | } 12 | 13 | const rswContent: RswInfo = { 14 | status: '', 15 | name: '', 16 | build: '', 17 | error: '', 18 | path: '', 19 | }; 20 | 21 | const rswInfo = path.resolve(process.cwd(), '.rsw', 'rsw.info'); 22 | const rswErr = path.resolve(process.cwd(), '.rsw', 'rsw.err'); 23 | const rswCrates = path.resolve(process.cwd(), '.rsw', 'rsw.crates'); 24 | 25 | const getVal = (line: string): string[] => line.split(' :~> ') || []; 26 | 27 | export const getCrates = (): Record => { 28 | const crates: string[] = []; 29 | const cratesPath: string[] = []; 30 | if (fs.existsSync(rswCrates)) { 31 | const content = fs.readFileSync(rswCrates, { encoding: 'utf8' }); 32 | content.split('\n').forEach(line => { 33 | const val = getVal(line); 34 | if (val.length > 0) { 35 | val?.[0] && crates.push(val?.[0]); 36 | val?.[1] && cratesPath.push(val?.[1]); 37 | } 38 | }) 39 | } 40 | return { crates, cratesPath }; 41 | } 42 | 43 | export const watch = (callback: (opts: RswInfo) => void, isInit: boolean) => { 44 | fs.watchFile(rswInfo, { 45 | bigint: false, 46 | interval: 300, 47 | persistent: true, 48 | }, () => { 49 | if (!fs.existsSync(rswInfo)) return; 50 | const rl = readline.createInterface({ 51 | input: fs.createReadStream(rswInfo), 52 | crlfDelay: Infinity 53 | }); 54 | 55 | rl.on('line', (line) => { 56 | const [, cratesPath] = getVal(line); 57 | switch (true) { 58 | case /\[RSW::OK\]/.test(line): 59 | rswContent.status = 'ok'; 60 | break; 61 | case /\[RSW::ERR\]/.test(line): 62 | rswContent.status = 'err'; 63 | break; 64 | case /\[RSW::NAME\]/.test(line): 65 | rswContent.name = cratesPath; 66 | break; 67 | case /\[RSW::PATH\]/.test(line): 68 | rswContent.path = cratesPath; 69 | break; 70 | case /\[RSW::BUILD\]/.test(line): 71 | rswContent.build = cratesPath; 72 | break; 73 | } 74 | }); 75 | 76 | rl.on('close', () => { 77 | if (rswContent.status === 'err') { 78 | rswContent.error = fs.readFileSync(rswErr, { encoding: 'utf8' }); 79 | } else { 80 | rswContent.error = ''; 81 | } 82 | if (isInit) callback(rswContent); 83 | isInit = false; 84 | }) 85 | }) 86 | } 87 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "ESNext", 4 | "target": "es2017", 5 | "lib": ["ESNext", "DOM"], 6 | "esModuleInterop": true, 7 | "strict": true, 8 | "strictNullChecks": true, 9 | "moduleResolution": "Node", 10 | "resolveJsonModule": true 11 | }, 12 | "exclude": [ 13 | "**/dist", 14 | "**/node_modules", 15 | "**/test" 16 | ] 17 | } --------------------------------------------------------------------------------