web高德maker动画_Web Maker —我如何构建一个快速的离线前端游乐场

呼延沈义
2023-12-01

web高德maker动画

by kushagra gour

由kushagra gour

Web Maker —我如何构建一个快速的离线前端游乐场 (Web Maker — How I built a fast, offline front-end playground)

Web Maker is a Chrome extension that gives you a blazing fast and offline front-end playground — right inside your browser.

Web Maker是一个Chrome扩展程序,可让您在浏览器内部快速,离线地访问前端平台。

It’s used daily by thousands of developers around the world and has a 5 star rating from 700+ users. It was also a homepage featured extension on the Chrome Webstore, twice!

全球每天有成千上万的开发人员在使用它,并获得700多个用户5星评级 。 这也是Chrome Webstore上首页功能扩展的两倍!

You can use Web Maker to play with HTML, CSS and JavaScript right in the browser without any external editor or specific setup. You can use things like Angular, React, Sass, Babel, or Atomic CSS — just like that.

您可以使用Web Maker在浏览器中直接播放HTML,CSS和JavaScript,而无需任何外部编辑器或特定设置。 您可以使用Angular,React,Sass,Babel或Atomic CSS之类的东西。

为什么我做网络制造商 (Why I made web maker)

If you’re a front-end developer, you’ve probably tried one or more of the code playgrounds out there — like CodePen, JSBin, JSFiddle — to figure out code issues or to discuss snippets and logic pieces with colleagues.

如果您是前端开发人员,则可能已经尝试过一个或多个代码游乐场(例如CodePen,JSBin,JSFiddle)来找出代码问题或与同事讨论代码片段和逻辑部分。

They’re all great and do the job perfectly.

他们都很出色,可以完美地完成工作。

But I’ve always felt a slight friction in using them over the internet — there’s an inherent delay between starting them up and being able to use them.

但是我一直感觉到在Internet上使用它们时会遇到一些摩擦-在启动它们和使用它们之间存在固有的延迟。

I also wanted a quick way to hack stuff while traveling or waiting at the airport, where you’re mostly offline. I could go with traditional editor and browser thing, but that requires a bit of setup.

我还希望有一种快速的方法来旅行或在机场(大多数情况下都处于离线状态)等待时破解东西。 我可以使用传统的编辑器和浏览器,但这需要一些设置。

When I thought more about it, I realized there are many places in the world with limited or no internet connectivity at all. People who want to learn and do web development there can’t use these online playgrounds. That shouldn’t stop them from learning and creating things!

当我对此进行更多思考时,我意识到世界上有很多地方根本没有互联网连接,或者根本没有互联网连接。 想要学习和进行Web开发的人不能使用这些在线游乐场。 那不应该阻止他们学习和创造东西!

I tried looking for something that could give me what I wanted, but couldn’t find any. And so Web Maker was born.

我试图寻找可以满足我需求的东西,但找不到任何东西。 因此,Web Maker诞生了。

我是如何制作Web Maker的 (How I made Web Maker)

The initial version of Web Maker was very basic. It had three editable sections (which were CodeMirror instances) for HTML, CSS, and JavaScript each. Whenever code was updated, it was combined into an HTML string with everything placed inline. This HTML string was then dumped inside an iframe document and rendered.

Web Maker的初始版本非常基础。 它有三个可编辑部分(分别是CodeMirror实例),分别用于HTML,CSS和JavaScript。 每当更新代码时,它就会组合成一个HTML字符串,所有内容都内联。 然后将此HTML字符串转储到iframe文档中并进行呈现。

This process has changed over time and multiple features have shipped since then. There are many interesting decisions, features, logic pieces and challenges that I’ll share in this article.

此后,此过程已发生变化,并且此后已发布了多个功能。 我将在本文中分享许多有趣的决策,功能,逻辑部分和挑战。

Chrome扩展程序-终极发行平台 (Chrome extension — the ultimate distribution platform)

I wanted a very simple distribution platform for Web Maker since it was in early stages. I also wanted something with a wide reach, so I chose to make it a Chrome extension.

因为Web Maker处于早期阶段,所以我希望它提供一个非常简单的发行平台。 我还想要范围广泛的产品,因此我选择将其作为Chrome扩展程序。

The Chrome Web Store is a breeze to use. Pushing an update is very easy and quick. The Chrome extension platform also offers capabilities that can be leveraged into interesting features. One example in Web Maker is screenshot capture of preview. It uses the captureVisibleTab API to grab the preview iframe’s screenshot and then the downloads API to download it for you with a click of a button.

Chrome网上应用店轻而易举地使用。 推送更新非常简单快捷。 Chrome扩展程序平台还提供了可以利用为有趣功能的功能。 Web Maker中的一个示例是预览的屏幕截图捕获。 它使用captureVisibleTab API来获取预览iframe的屏幕截图,然后使用downloads API只需单击一下按钮即可为您下载它。

用香草JavaScript和CSS编写 (Written in vanilla JavaScript and CSS)

I have worked with JavaScript frameworks like Angular and Vue in small and large-scale applications. I could have used any of the available frameworks here too. But for Web Maker I decided to go vanilla to challenge myself and see how far could I go without a framework until the codebase becomes spaghetti. I wanted to use all the knowledge I have gained from working with those frameworks and libraries to keep the code sane, organized and DRY.

我曾经在小型和大型应用程序中使用过像AngularVue这样JavaScript框架。 我也可以在这里使用任何可用的框架。 但是对于Web Maker,我决定去挑战自己,看看没有框架的情况下我能走多远,直到代码库成为意大利面条为止。 我想利用从这些框架和库中获得的所有知识来使代码保持理智,有条理和干燥。

As most projects do, I started with a single script.js JavaScript file. To keep the codebase modular and organized, I moved big independent chunks out of it into separate files as needed (for example, utils.js and dropdown.js).

与大多数项目一样,我从一个script.js JavaScript文件开始。 为了使代码库保持模块化和井井有条,我根据需要将较大的独立块移出了单独的文件(例如utils.jsdropdown.js )。

Apart from that I also wrote a small directive system (like in angular/Vue) that lets me do things like:

除此之外,我还编写了一个小型指令系统(例如angular / Vue),可以执行以下操作:

<a class=”btn” d-click=”someFunction”>Button</a>

and

<input d-change=”someOtherFunction” >

Note: I couldn’t use inline scripts like onclick or onchange. They’re not allowed in Chrome extensions due to security restrictions.

注意:我无法使用诸如onclickonchange类的内联脚本。 由于安全限制,Chrome扩展程序中不允许使用它们。

For CSS too, Web Maker only relies on browser provided features like CSS variables. Since I developed Web Maker just for Chrome, I can safely use new upcoming features without worrying about cross browser support — another perk of building a Chrome extension.

对于CSS而言,Web Maker也仅依靠浏览器提供的功能(如CSS变量)。 由于我仅针对Chrome开发了Web Maker,因此我可以安全地使用即将推出的新功能,而不必担心跨浏览器支持-构建Chrome扩展程序的另一个好处。

I plan to look into web components to break the UI into independent components.

我计划研究Web组件,以将UI分成独立的组件。

预览生成 (Preview generation)

As I mentioned earlier, in the first version of the app, the final preview was simply an HTML string which had user’s CSS as an inlined style tag and user’s JavaScript as inlined script tag. And this HTML string was written in a temporary HTML file which loaded in an iframe. The HTML file looked something like this:

正如我前面提到的,在该应用程序的第一个版本中,最终预览只是一个HTML字符串,其中包含用户CSS作为内嵌样式标签,而用户JavaScript作为内嵌脚本标签。 然后,此HTML字符串写入了一个临时HTML文件中,该文件已加载到iframe中。 HTML文件如下所示:

<html> <head>  <style>   user CSS here...  </style> </head> <body>  user html here...  <script>user JS here...</script>  </body></html>

But while working on the version 2.0 of Web Maker I found that on Chrome Canary (v57 at the time) the preview was no longer running the user’s JavaScript. Upon inspection, I found a chrome policy error in the developer console that said:

但是,在使用Web Maker 2.0版时,我发现在Chrome Canary(当时为v57)上,预览不再运行用户JavaScript。 经过检查,我在开发人员控制台中发现了一个chrome策略错误,内容为:

Refused to execute inline script because it violates the following Content Security Policy directive…
拒绝执行内联脚本,因为它违反了以下内容安全策略指令…

Now, I already knew that the Content Security Policy (CSP) didn’t allow me to put inline scripts into a Chrome extension’s markup, and I had all my JavaScript in separate files. This was different. Starting with Chrome 57, the CSP had started applying to preview iframes, too. The solution was to move the user’s JavaScript from inline to a separate JavaScript file.

现在,我已经知道内容安全策略(CSP)不允许我将内联脚本放入Chrome扩展程序的标记中,并且我所有JavaScript都放在单独的文件中。 这是不同的。 从Chrome 57开始,CSP也开始应用到预览iframe。 解决方案是将用户JavaScript从内联移动到单独JavaScript文件。

So I refactored the logic and now on every refresh, the user’s JavaScript is written into a temporary JavaScript file. This is then loaded in the preview iframe.

因此,我重构了逻辑,现在每次刷新时,用户JavaScript都会写入一个临时JavaScript文件中。 然后将其加载到预览iframe中。

Note that the preview iframe isn’t refreshed on every keystroke in the editor. The refresh is debounced on user input — so the preview is only refreshed when the user has stopped typing for a short duration. Otherwise, it would result in a lot of unnecessary refreshes as the user is typing.

请注意,并不是在编辑器中的每次击键操作时都刷新预览iframe。 刷新将在用户输入时被消除抖动 -因此,仅当用户在短时间内停止键入时,刷新预览。 否则,这将导致在用户键入时出现许多不必要的刷新。

CSS updating is a little different though. Unlike HTML and JavaScript where the complete iframe is refreshed, CSS updates whenever it’s edited in the style tag of the iframe. There is no file writing or iframe refresh involved. Hence, for CSS, the preview refresh is a lot faster.

CSS更新有些不同。 与刷新完整iframeHTML和JavaScript不同的是,只要在iframe的样式标签中对其进行编辑,CSS就会更新。 不涉及文件写入或iframe刷新。 因此,对于CSS,预览刷新要快得多。

JavaScript中的无限循环预防 (Infinite loop prevention in JavaScript)

As I mentioned above, the preview refreshes as soon as the user stops typing. At this point, it’s possible that user paused while writing a loop in JavaScript, resulting in a partial form. Something like:

如上所述,用户停止键入后,预览就会刷新。 此时,用户可能会在用JavaScript编写循环时暂停,从而导致部分形式。 就像是:

for (var i = 0; i<10; [user_cursor_here]) {}

The increment/decrement condition is missing from this JavaScript — so if it was put inside the iframe, the browser tab would choke! Such cases need to be prevented by any playground like Web Maker.

此JavaScript中缺少递增/递减条件-因此,如果将其放在iframe中,则浏览器选项卡会阻塞! Web Maker等任何游乐场都需要防止此类情况。

Web Maker does this by parsing user’s JavaScript and modifying all the loops so that each loop keeps checking if it hasn’t taken too long to run.

Web Maker通过解析用户JavaScript并修改所有循环来做到这一点,以便每个循环都可以检查它是否花了很长时间才运行。

Basically, this:

基本上,这是:

for (var i = 0; i<10; [user_cursor_here]) {}

is converted to:

转换为:

var _wmloopvar1 = Date.now();for (var i = 0; i<10; [user_cursor_here]) { if (Date.now() - _wmloopvar1 > 1000) { break; }\}

If we spend more than a second inside a loop, we break and come out.

如果我们在一个循环中花费超过一秒钟的时间,我们就会中断并出来。

I use Esprima for all this instrumentation. Here is a detailed blog post on how it’s done. Note, the logic mentioned in the blog post was recently refactored to be more efficient, as suggested by Esprima’s author Ariya Hidayat.

我将Esprima用于所有这些工具。 这是有关如何完成的详细博客文章 。 注意,正如Esprima的作者Ariya Hidayat所建议的那样,博客文章中提到的逻辑最近被重构为更有效。

预处理器 (Preprocessors)

Like most front-end playground, Web Maker gives many preprocessors for each HTML, CSS, and JavaScript.

像大多数前端游乐场一样,Web Maker为每种HTML,CSS和JavaScript提供了许多预处理器。

Adding any preprocessor in the app requires getting hold of its transpiler (source-to-source compiler) and understanding how it transpiles the input code. You also need to know that it displays transpilation errors besides every line.

在应用程序中添加任何预处理器都需要掌握其编译器(源到源编译器)并了解其如何编译输入代码。 您还需要知道,除每行外,它还会显示翻译错误。

Now almost all of the online playgrounds out there transpile your code on their server. But Web Maker has no server — it sits in your browser and runs in your browser.

现在,几乎所有的在线游乐场都在您的服务器上转换您的代码。 但是Web Maker没有服务器-它位于您的浏览器中并在您的浏览器中运行。

Many transpilers are meant to be run only in a NodeJS environment, so I made an effort to bundle them into browser compatible code. Web Maker uses transpilers like CoffeeScript, SASS, and Babel.

许多编译器只应在NodeJS环境中运行,因此我努力将它们捆绑到浏览器兼容的代码中。 Web Maker使用诸如CoffeeScriptSASSBabel的编译器。

Upon every change in the editor, the user’s code is sent to the appropriate transpiler, and then the transpiled code is sent to preview generation. I used a Promise based API for transpiling code for two reasons:

在编辑器中进行每次更改后,都会将用户代码发送到适当的编译器,然后将已编译的代码发送到预览生成。 我使用基于Promise的API进行代码转换有两个原因:

  1. SASS transpiler is not synchronous. It uses a worker to convert the SASS code to CSS on a separate thread.

    SASS编译器不同步。 它使用工作程序在单独的线程上将SASS代码转换为CSS。
  2. I might move other transpilers to a separate worker too. Source compilation can sometimes take a long time. It can also result in infinite loops, blocking the main UI thread in such cases. Thus it’s better to move them to separate worker.

    我也可能将其他编译器也转移到单独的工作人员那里。 源代码编译有时可能需要很长时间。 在这种情况下,它还会导致无限循环,从而阻塞主UI线程。 因此,最好将它们移到单独的工人上。

For example, the function that converts JavaScript looks like this in a broad sense:

例如,转换JavaScript的函数在广义上如下所示:

function computeJs() { var d = deferred(); if (jsMode === JsModes.COFFEESCRIPT) {    try {   code = CoffeeScript.compile(code, { bare: true });  } catch (e) {   showErrors(    'js',    [{ lineNumber: e.location.first_line, message: e.message }]   );     } finally {   d.resolve(code);  }}

存储 (Storage)

Version 2.0 of Web Maker shipped with a very important capability to store user creations.

Web Maker 2.0版附带了非常重要的功能来存储用户创建的内容。

I decided to use localStorage. So, even if you are working on a different machine you can save all your Web Maker settings like indentation size, theme etc.

我决定使用localStorage 。 因此,即使您在其他计算机上工作,也可以保存所有Web Maker设置,例如缩进大小,主题等。

It would have been great if even the creations were stored in synced storage like the extension’s settings. That way they’d be accessible across devices. Synced storage come with comparatively lower space quota, however, and I didn’t want to risk the saved work.

如果将创建内容(例如扩展程序的设置)存储在同步存储中,那就太好了。 这样,就可以跨设备访问它们。 但是,同步存储具有相对较低的空间配额,我不想冒险保存工作。

You may be able to save all your work on the cloud in future versions!

您也许可以在将来的版本中将所有工作保存在云中!

Web Maker also has an option to export and import all the saved creations.

Web Maker还可以选择导出和导入所有保存的创建。

基于开放式Web技术和开放源代码库 (Built on open web technologies and open-source libraries)

Web Maker is build over multiple awesome open source libraries and is itself open source.

Web Maker建立在多个很棒的开源库之上,并且它本身就是开源的

The three editor panes where you actually type the code is is built with CodeMirror. CodeMirror comes with a lot of add-ons and modes, which allows Web Maker to support code autocompletion, code folding, syntax highlighting, and themes.

您在其中实际键入代码的三个编辑器窗格是使用CodeMirror构建的 。 CodeMirror带有许多附加组件和模式,这使Web Maker可以支持代码自动完成,代码折叠,语法突出显示和主题。

Thanks to Esprima, you can see generic JavaScript errors in your code as you type in the editor. As I mentioned before, Esprima also helps prevent infinite loops.

多亏了Esprima ,您在编辑器中键入代码时就可以看到代码中的一般JavaScript错误。 如前所述,Esprima还有助于防止无限循环。

Apart from that Web Maker uses Split.js, Hint.css, Emmet, Inlet.js, and even Web Maker! Yes, Web Maker is made inside Web Maker.

除此之外,Web Maker还使用Split.jsHint.cssEmmetInlet.js甚至Web Maker! 是的,Web Maker是在Web Maker内部制作的。

挑战性 (Challenges)

There were many slowdowns during the development, but I would like to talk about two major ones.

在开发过程中有许多放慢的速度,但是我想谈谈两个主要的放慢速度。

As I mentioned, when I was working on version 2.0, I discovered a major change in Chrome 57 which broke the ability to put inline scripts into the extension’s markup.

正如我所提到的,当我使用2.0版时,我发现Chrome 57发生了重大变化,这打破了将内联脚本放入扩展的标记中的功能。

There was also a feature shipped with 2.0 that allowed the user to add any number of external JavaScript or CSS libraries. When the user enters a JavaScript library URL, it is added as a script tag with the src attribute set to the URL. Chrome extension CSP, apart from preventing inline JavaScript, also restricts JavaScript from loading domains except those mentioned in the CSP — which meant that user won’t be able to load external JavaScript from any random domain.

2.0附带的功能还允许用户添加任意​​数量的外部JavaScript或CSS库。 当用户输入JavaScript库URL时,它将添加为src属性设置为URL的脚本标记。 Chrome扩展程序CSP除了阻止内联JavaScript外,还限制了JavaScript无法加载CSP中提到的域之外的域-这意味着用户将无法从任何随机域中加载外部JavaScript。

This is currently partially solved by whitelisting all the major CDNs in the manifest.json file. It’s still not perfect as user cannot load JavaScript from any domain apart from those.

目前,这可以通过将manifest.json文件中的所有主要CDN列入白名单来部分解决。 由于用户无法从任何域中加载JavaScript,因此它仍然不是完美的。

Another big thing that hit me was the Preview Screenshot feature. This feature allows the user to grab a screenshot of the current preview and download it as an image with a click of a button. This feature required me to bring in two more permissions: downloads and <all_urls>.

让我大吃一惊的是预览屏幕截图功能。 此功能使用户可以捕获当前预览的屏幕快照,然后单击按钮即可将其下载为图像。 此功能要求我再添加两个权限: downloads<all_ur ls>。

&lt;all_urls> is actually a weird permission, but it’s a must-have if you want to use the captureVisibleTab API. Here’s how it looks while installing the extension:

lt;all_ur ls>实际上是一个奇怪的权限,但是如果您要e the captureVisi bleTab API, e the captureVisi必不可少的。 安装扩展程序时的外观如下:

The first line is pretty scary for anyone installing the extension.

对于安装此扩展程序的任何人,第一行都非常可怕。

Additionally, if you add a new permission for a new version of an extension, Chrome disables the installed extension and shows a popup that the extension requires new permission.

此外,如果您为新版本的扩展程序添加新权限,Chrome会禁用已安装的扩展程序,并显示一个弹出窗口,提示该扩展程序需要新权限。

This alarmed some users who already had Web Maker installed. Many people who saw this new permission being asked, didn’t allow it, and uninstalled it right away.

这使一些已经安装了Web Maker的用户感到震惊。 许多看到此新许可的人都被要求,不允许这样做并立即将其卸载。

After this particular release, I saw a big spike in the number of uninstalls.

在此特定发行版之后,我看到卸载数量激增。

The moral of the story: Be careful with the permissions you add to your app. Unless required for core-functioning, always go for optional in-app permissions.

故事的寓意:小心添加到应用程序中的权限。 除非核心功能需要,否则请务必获得可选的应用内权限。

总结一下 (Summing it up)

Web Maker has come quite far in terms of usability, features, and adoption. Being quick and offline makes it usable in huge number of scenarios, from doing web experiments on a train/plane to teaching a classroom of students.

Web Maker在可用性,功能和采用方面取得了很大进步。 快速且离线使它可用于大量场景,从在火车/飞机上进行网络实验到为学生教室授课。

Web Maker can also be used by professionals and beginners in areas where the internet is slow or not present at all.

专业人士和初学者也可以在互联网速度缓慢或根本没有互联网的地区使用Web Maker。

And I am sure Web Maker can help FreeCodeCamp campers tremendously in their learnings and practice.

而且我确信Web Maker可以极大地帮助FreeCodeCamp营员的学习和实践。

Moreover, Web Maker is open-source, so everyone is welcome to suggest and implement features they think would make it more useful. It could be your first step to learn some practical JavaScript by contributing.

此外,Web Maker是开源的 ,因此欢迎每个人提出并实施他们认为会使其更有用的功能。 通过贡献力量学习一些实用JavaScript可能是您的第一步。

If you have any suggestions, comments or questions, tweet them @webmakerApp. I am excited to hear your feedback and experience with it.

如果您有任何建议,意见或问题,请在@webmakerApp上发布 。 我很高兴听到您的反馈和使用经验。

Install Web Maker and give it a spin and follow Web Maker on Medium for tips, tricks and how-to articles.

安装Web Maker并试用一下,然后在Medium上关注Web Maker ,获取提示,技巧和操作方法文章。

翻译自: https://www.freecodecamp.org/news/web-maker-how-i-built-a-fast-offline-front-end-playground-9fe3629bc86f/

web高德maker动画

 类似资料: