How iMove Enables Seamless In-Browser Code Execution for Developers
iMove, a reusable, function‑oriented JavaScript library, adds right‑click online code execution to its visual workflow, eliminating installation, simplifying testing with mock inputs, handling ES module imports via native browser support, CDN transforms, dynamic imports, and custom events to deliver instant, visual results.
iMove is a reusable, function‑oriented, visual‑workflow JavaScript library. For developers, iMove lets you write node functions, export the code, and use it directly in a project, making development convenient.
The online code‑execution feature was added to let users right‑click a node and run its code instantly, reducing installation steps and improving the user experience.
Prelude
A teammate asked how to test newly written node code. The steps were:
Install @imove/cli.
Run imove -d in the project root.
Add code with logic.invoke('trigger') to a component.
Start the project, open the console panel, and filter log messages.
The process felt tedious, costly, and the results were not intuitive, prompting the need for a right‑click online execution feature.
Benefits of Right‑Click Execution
Zero installation cost: Code runs in the browser without needing CLI tools.
Result visualization: Execution results are displayed visually instead of digging through the console.
Online mock input: Developers can mock inputs directly, greatly improving testing efficiency.
Test case saving: Input/output pairs can be saved as test cases to ensure code quality.
Exploration 1: Where Does Node Code Run?
Two options were considered: running code directly in the browser or starting a local service that bundles the code and sends it back to the browser. iMove chose the former to keep the barrier low, but a simple eval is insufficient.
Exploration 2: How to Run import/export
Each node is compiled into a separate .js file, so import statements are supported. Browsers natively support ES modules, so a <script type="module"> tag is required.
# File structure
index.html
main.mjs <!--index.html-->
<script type="module">
import sayHello from './main.js';
say('Hello iMove!');
</script> // main.js
const say = (words) => console.log(words);When importing a package like lodash.get, the browser treats it as a relative path, causing errors. Using an HTTP URL such as import get from 'https://unpkg.com/lodash.get' works, but the package is CommonJS (CJS) while the browser expects ES Module (ESM), leading to further failures.
2) SystemJS Attempt
SystemJS can load ES modules, but older versions that supported CJS are no longer maintained, and the approach introduces performance concerns.
3) New‑Generation JS Module CDN Hosting
CDNs like unpkg and jspm can serve ESM versions of packages. Experiments showed that loading lodash.get from jspm works while unpkg may not.
Exploration 3: Merging Multiple Files into a Single Executable
iMove’s output consists of multiple files, which would require an HTTP server for relative imports. Merging them into a single file eliminates this need. Example before merging:
// a.js
import get from 'lodash.get';
const obj = {text: 'a', say: () => console.log(get(obj, 'text'))};
export default obj;
// b.js
import get from 'lodash.get';
const obj = {text: 'b', say: () => console.log(get(obj, 'text'))};
export default obj;
// main.js
import a from './a';
import b from './b';
a.say();
b.say();After merging, dynamic imports and careful naming avoid global conflicts:
// merged.js
const run = async () => {
const modA = await (async () => {
const get = (await import('https://jspm.dev/lodash.get')).default;
const obj = {text: 'a', say: () => console.log(get(obj, 'text'))};
return obj;
})();
const modB = await (async () => {
const get = (await import('https://jspm.dev/lodash.get')).default;
const obj = {text: 'b', say: () => console.log(get(obj, 'text'))};
return obj;
})();
modA.say();
modB.say();
};
run();Note that the original import statements become dynamic imports inside function bodies.
Exploration 4: Communicating Between Scripts
To execute code strings without eval, a <script type="module"> element can be created dynamically:
const script = document.createElement('script');
script.type = 'module';
script.text = 'code here';
document.body.appendChild(script);After execution, results can be communicated back using custom events:
// Listen for event
document.addEventListener('customEvent', function (evt) {
console.log(evt.detail);
}, false);
// Dispatch event
document.dispatchEvent(new CustomEvent('customEvent', {detail: {text: 'iMove'}}));Summary
The article walked through the challenges of adding online node‑code execution to iMove and resolved them mainly through the http‑import concept, leveraging Deno’s lightweight approach and modern CDN‑served JavaScript modules. This low‑cost, low‑risk solution improves developer experience and showcases a new direction for package management.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Taobao Frontend Technology
The frontend landscape is constantly evolving, with rapid innovations across familiar languages. Like us, your understanding of the frontend is continually refreshed. Join us on Taobao, a vibrant, all‑encompassing platform, to uncover limitless potential.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
