首页 > web前端 > js教程 > 如何使用香草JavaScript编写原子包装

如何使用香草JavaScript编写原子包装

Joseph Gordon-Levitt
发布: 2025-02-18 12:43:10
原创
772 人浏览过

如何使用香草JavaScript编写原子包装

>本文是由Vildan Softic审查的。感谢SitePoint所有的同行评审员制作SitePoint内容的最佳状态! >

钥匙要点

>利用babel进行跨越JavaScript代码,以确保与Atom基于铬的环境的兼容性,从而增强ES2015功能的使用,同时保持未来的适应性。

>像npm模块一样,将您的原子包构建。
    >实现必需软件包生命周期方法,例如`activate()`,`deactivate()```''和`serialize()`在您的主javaScript文件中,在包装的使用周期内管理状态和行为。
  • >采用Atom的序列化系统来维护跨会话的软件包状态,以确保保留用户数据和设置并准确地恢复。> 通过创建自定义视图并利用Atom的API添加可配置的设置,菜单和keymaps,可以增强用户交互,从而使您的软件包既通用又有用户。
  • 理解原子
  • ATOM是一个基于github的电子框架编写的节点。JS和基于铬的应用。这意味着从技术上讲,它是在桌面上运行的Web应用程序。原子的内部功能分为微小的核心软件包;它们的开发方式与社区的任何其他软件包相同。尽管它们都是用CoffeeScript编写的,但可以用简单的JavaScript编写它们,或者通过Babel将其写入。
  • >激活全埃斯2015支持babel
  • Babel是源代码编译器;将Ecmascript 2015(以前称为ES6)代码变成Ecmascript 5代码。由于环境是铬,因此已经有许多支持的ES2015功能可用。但是,我建议使用Babel传输您的代码,而不是总是查找哪些实施。在后来的版本中 - 当铬在ES2015中得到更好的支持时,您可以再次停用Babel并保持代码库(几乎)未触及的代码。
  • 要激活用babel进行转移,每个文件都需要一个“使用babel”;一开始的语句,类似于Ecmascript 5中的严格模式。这还使您能够决定要转录哪些文件,而不是通过省略语句。

    package.json

    >它有助于将Atom软件包视为NPM模块。您对API的访问与在Node.js上运行的任何工具相同。因此,可以添加所需的任何NPM依赖性。还需要一个软件包。包含您项目的所有元数据。基本文件应如下:

    <span>{
    </span>  <span>"name": "your-package",
    </span>  <span>"main": "./lib/main",
    </span>  <span>"version": "0.1.0",
    </span>  <span>"description": "A short description of your package",
    </span>  <span>"keywords": [
    </span>    <span>"awesome"
    </span>  <span>],
    </span>  <span>"repository": "https://github.com/<your-name>/<package>",
    </span>  <span>"license": "MIT",
    </span>  <span>"engines": {
    </span>    <span>"atom": ">=1.0.0 <2.0.0"
    </span>  <span>},
    </span>  <span>"dependencies": {
    </span>  <span>}
    </span><span>}
    </span>
    登录后复制
    登录后复制
    登录后复制

    重要的密钥是主要的 - 定义软件包的主要入口点(默认为index.js/index.coffee)和引擎 - 讲述了您的软件包运行哪个版本的原子。还有一组可选的键可用,在“ WordCount”软件包文档>(extact package.json)>中记录

    软件包源代码

    >您的所有软件包代码都属于顶级目录lib/。我建议还将您的入口点放在此文件夹中,因为它可以使结构保持清洁并更容易扫描项目。

    >您的主文件必须是一个单身对象,该对象维护包装的整个生命周期。即使您的软件包仅由单个视图组成,它也将从此对象进行管理。您的入口点需要一个激活方法,但也应具有

    >可选

    deactivate()和serialize()。 激活您的软件包

    <span>// lib/main.js
    </span><span>'use babel';
    </span>
    <span>// This is your main singleton.
    </span><span>// The whole state of your package will be stored and managed here.
    </span><span>const YourPackage = {
    </span>  <span>activate (state) {
    </span>    <span>// Activates and restores the previous session of your package.
    </span>  <span>},
    </span>  <span>deactivate () {
    </span>    <span>// When the user or Atom itself kills a window, this method is called.
    </span>  <span>},
    </span>  <span>serialize () {
    </span>    <span>// To save the current package's state, this method should return
    </span>    <span>// an object containing all required data.
    </span>  <span>}
    </span><span>};
    </span>
    <span>export default YourPackage;
    </span>
    登录后复制
    登录后复制
    登录后复制
    acivate()函数是唯一必需的方法。在此处初始化所有模块,视图或助手。它通过一个对象,其中包含包装的先前序列化状态。如果您不在包装中序列化任何内容,则将是一个空的对象。这意味着,这完全取决于您和您的软件包架构。

    停用

    >事件订阅

    一个软件包通常会订阅多个事件,例如添加自定义命令,收听更改或修改文件。可以将它们捆绑到CompositedIsable()的实例中,因此,它们都可以立即被处置。

    >

    序列化所有内容!

    >

    序列化是一个功能强大但又可选的原子软件包功能。当窗口从上一个会话中关闭,刷新或还原时,会序列化/避难所化。您可以定义哪些组件以及多少组件应序列化数据。重要的是它返回JSON。如果您有视图,并且希望能够刷新它,则需要使其与序列化和挑选化兼容。

    >

    这个非常基本的组件采用一个对象,该对象将用作组件的内部数据。然后,您的组件可能会与数据进行一些工作,并且可以通过serialize()方法序列化其状态。

    >
    <span>{
    </span>  <span>"name": "your-package",
    </span>  <span>"main": "./lib/main",
    </span>  <span>"version": "0.1.0",
    </span>  <span>"description": "A short description of your package",
    </span>  <span>"keywords": [
    </span>    <span>"awesome"
    </span>  <span>],
    </span>  <span>"repository": "https://github.com/<your-name>/<package>",
    </span>  <span>"license": "MIT",
    </span>  <span>"engines": {
    </span>    <span>"atom": ">=1.0.0 <2.0.0"
    </span>  <span>},
    </span>  <span>"dependencies": {
    </span>  <span>}
    </span><span>}
    </span>
    登录后复制
    登录后复制
    登录后复制

    为了使所有这些有用,必须在包装中调用和序列化此组件。

    <span>// lib/main.js
    </span><span>'use babel';
    </span>
    <span>// This is your main singleton.
    </span><span>// The whole state of your package will be stored and managed here.
    </span><span>const YourPackage = {
    </span>  <span>activate (state) {
    </span>    <span>// Activates and restores the previous session of your package.
    </span>  <span>},
    </span>  <span>deactivate () {
    </span>    <span>// When the user or Atom itself kills a window, this method is called.
    </span>  <span>},
    </span>  <span>serialize () {
    </span>    <span>// To save the current package's state, this method should return
    </span>    <span>// an object containing all required data.
    </span>  <span>}
    </span><span>};
    </span>
    <span>export default YourPackage;
    </span>
    登录后复制
    登录后复制
    登录后复制
    您要序列化的所有对象都需要序列化()方法。它必须返回一个“可序列化对象”,以及带有注册供应仪名称的Deserializer键。根据Atom的说法,“通常是班级本身的名称”。除此之外,一个类还需要静态求解方法。此方法将对象从以前的状态转换为真实对象。

    > 为了使所有这些都成为可能,您必须使用Atom.deserializers.add()。

    窗格和视图

    窗格是原子中的单个窗口。它包含所有称为“项目”的打开选项卡。这些窗格存储在Atom.workspace对象中。使用atom.workspace.getactivepane()您请求当前的活动窗格。窗格对象不包含任何DOM元素,而是Atom内部组件的所有实例(例如TextEditor,GutterContainer,NotificationManager)。了解这些窗格对于为您的软件包创建自定义视图至关重要。

    您必须使用JavaScript创建您要添加的任何其他自定义UI元素的视图或任何其他自定义UI元素。 Atom完全由Web组件构建,但是您不必这样做。自定义模式的一个非常基本的示例可以如下。

    >

    atom.workspace.addmodalpanel()方法在Atom的工作区中添加了模态元素。如果要向窗格添加自定义视图(例如,对于设置页面),则需要更多的工作。

    >
    <span>// lib/main.js
    </span><span>import <span>{ CompositeDisposable }</span> from 'atom';
    </span>
    <span>const YourPackage = {
    </span>  <span>subscriptions: null,
    </span>
      <span>activate (state) {
    </span>    <span>// Assign a new instance of CompositeDisposable...
    </span>    <span>this.subscriptions = new CompositeDisposable();
    </span>
        <span>// ...and adding commands.
    </span>    <span>this.subscriptions.add(
    </span>      atom<span>.commands.add('atom-workspace', {
    </span>        <span>'your-package:toggle': this.togglePackage
    </span>      <span>})
    </span>    <span>);
    </span>  <span>},
    </span>
      <span>// When your package get's deactivated, all added
    </span>  <span>// subscriptions will be disposed of at once.
    </span>  <span>deactivate () {
    </span>    <span>this.subscriptions.dispose();
    </span>  <span>},
    </span>
      <span>togglePackage () {
    </span>    <span>// Code to toggle the package state.
    </span>  <span>}
    </span><span>};
    </span>
    登录后复制
    登录后复制
    制作包装可配置
    <span>// lib/fancy-component.js
    </span><span>class FancyComponent {
    </span>  <span>constructor (configData) {
    </span>    <span>this.data = configData;
    </span>  <span>}
    </span>
      <span>// This method will be called when the class
    </span>  <span>// is restored by Atom.
    </span>  <span>static deserialize (config) {
    </span>    <span>return new FancyComponent(config);
    </span>  <span>}
    </span>
      <span>// The returned object will be used to restore
    </span>  <span>// or save your data by Atom.
    </span>  <span>// The "deserializer" key must be the name of your class.
    </span>  <span>serialize () {
    </span>    <span>return {
    </span>      <span>deserializer: 'FancyComponent',
    </span>      <span>data: this.data
    </span>    <span>};
    </span>  <span>}
    </span>
      <span>doSomethingWithData () {}
    </span><span>}
    </span>
    <span>// Add class to Atom's deserialization system
    </span>atom<span>.deserializers.add(FancyComponent);
    </span>
    <span>export default FancyComponent;
    </span>
    登录后复制
    登录后复制

    >软件包配置应在JSON模式中描述。要添加设置,您的软件包对象需要带有数据的配置密钥。另外,您可以将配置移至config-schema.json文件并导入。这样可以使您的配置分开并组织结构。

    >

    这将在包装的设置页面上自动创建配置。所有受支持类型的列表可以在Atom API文档的“配置”页面上找到。您的设置对象以及所有其他软件包配置都存储在atom.config对象中。

    >获得和设置
    <span>// lib/main.js
    </span><span>import <span>FancyComponent</span> from './fancy-component';
    </span><span>import <span>SomeView</span> from './some-view';
    </span>
    <span>const YourPackage = {
    </span>  <span>fancyComponent: null,
    </span>  <span>someView: null,
    </span>
      <span>activate (state) {
    </span>    <span>// If the component has been saved at a previous session of Atom,
    </span>    <span>// it will be restored from the deserialization system. It calls your
    </span>    <span>// your components static 'deserialize()' method.
    </span>    <span>if (state.fancy) {
    </span>      <span>this.fancyComponent = atom.deserializers.deserialize(state.fancy);
    </span>    <span>}
    </span>    <span>else {
    </span>      <span>this.fancyComponent = new FancyComponent({ otherData: 'will be used instead' });
    </span>    <span>}
    </span>
        <span>// More activation logic.
    </span>  <span>},
    </span>
      <span>// As well as your component, your package has a serialize method
    </span>  <span>// to save the current state.
    </span>  <span>serialize () {
    </span>    <span>return {
    </span>      <span>fancy: this.fancyComponent.serialize(),
    </span>      <span>view: this.someView.serialize()
    </span>    <span>};
    </span>  <span>}
    </span><span>};
    </span>
    登录后复制
    登录后复制
    <span>// lib/custom-view-element.js
    </span><span>export default class YourPackageView {
    </span>  <span>constructor (state) {
    </span>    <span>this.data = state;
    </span>    <span>this.element = document.createElement('div');
    </span>    <span>this.message = document.createElement('span');
    </span>    <span>this.textNode = document.createTextNode(this.data.content);
    </span>
        <span>this.element.classList.add('your-package');
    </span>    <span>this.message.classList.add('your-package-message');
    </span>
        <span>this.message.appendChild(this.textNode);
    </span>    <span>this.element.appendChild(this.message);
    </span>  <span>}
    </span>
      <span>serialize () {
    </span>    <span>return {
    </span>      <span>data: this.data
    </span>    <span>};
    </span>  <span>}
    </span>
      <span>destroy () {
    </span>    <span>this.element.remove();
    </span>  <span>}
    </span>
      <span>getElement () {
    </span>    <span>return this.element;
    </span>  <span>}
    </span>
      <span>doSomethingWithData () {}
    </span><span>}
    </span>
    登录后复制
    >您可以使用get()和set()方法获取并设置配置的任何键。也可以获取Atom的一般设置或其他软件包的设置。如果您想与其他软件包进行互动,则需要提供和消费服务。

    >

    <span>{
    </span>  <span>"name": "your-package",
    </span>  <span>"main": "./lib/main",
    </span>  <span>"version": "0.1.0",
    </span>  <span>"description": "A short description of your package",
    </span>  <span>"keywords": [
    </span>    <span>"awesome"
    </span>  <span>],
    </span>  <span>"repository": "https://github.com/<your-name>/<package>",
    </span>  <span>"license": "MIT",
    </span>  <span>"engines": {
    </span>    <span>"atom": ">=1.0.0 <2.0.0"
    </span>  <span>},
    </span>  <span>"dependencies": {
    </span>  <span>}
    </span><span>}
    </span>
    登录后复制
    登录后复制
    登录后复制

    聆听更改

    要聆听更改,您可以观察更改的配置,或者将侦听器(称为o​​ndidchange())到关键路径。他们俩都返回一个可用于.dispose()退订的一次性。

    > 再次,将它们添加到Compositedisposable的实例中,您可以立即处理多个事件:>

    或单独处置它们:
    <span>// lib/main.js
    </span><span>'use babel';
    </span>
    <span>// This is your main singleton.
    </span><span>// The whole state of your package will be stored and managed here.
    </span><span>const YourPackage = {
    </span>  <span>activate (state) {
    </span>    <span>// Activates and restores the previous session of your package.
    </span>  <span>},
    </span>  <span>deactivate () {
    </span>    <span>// When the user or Atom itself kills a window, this method is called.
    </span>  <span>},
    </span>  <span>serialize () {
    </span>    <span>// To save the current package's state, this method should return
    </span>    <span>// an object containing all required data.
    </span>  <span>}
    </span><span>};
    </span>
    <span>export default YourPackage;
    </span>
    登录后复制
    登录后复制
    登录后复制

    用菜单和keymaps进行微调

    进行微调
    <span>// lib/main.js
    </span><span>import <span>{ CompositeDisposable }</span> from 'atom';
    </span>
    <span>const YourPackage = {
    </span>  <span>subscriptions: null,
    </span>
      <span>activate (state) {
    </span>    <span>// Assign a new instance of CompositeDisposable...
    </span>    <span>this.subscriptions = new CompositeDisposable();
    </span>
        <span>// ...and adding commands.
    </span>    <span>this.subscriptions.add(
    </span>      atom<span>.commands.add('atom-workspace', {
    </span>        <span>'your-package:toggle': this.togglePackage
    </span>      <span>})
    </span>    <span>);
    </span>  <span>},
    </span>
      <span>// When your package get's deactivated, all added
    </span>  <span>// subscriptions will be disposed of at once.
    </span>  <span>deactivate () {
    </span>    <span>this.subscriptions.dispose();
    </span>  <span>},
    </span>
      <span>togglePackage () {
    </span>    <span>// Code to toggle the package state.
    </span>  <span>}
    </span><span>};
    </span>
    登录后复制
    登录后复制
    >菜单和keymaps使您的包装功能可在原子环境中访问用户。它们链接到您界面的特定命令。如果您的软件包可以切换,打开视图,执行一些自定义操作或其他任何操作,则应向用户使用。

    >

    添加菜单

    >菜单定义可以作为JSON文件存储在菜单/顶级目录中,也可以在包装的菜单键中存储。以下示例将命令添加到“软件包”菜单栏和编辑器的上下文菜单中。右键单击编辑器内部时出现上下文菜单。

    >

    keymaps

    <span>// lib/fancy-component.js
    </span><span>class FancyComponent {
    </span>  <span>constructor (configData) {
    </span>    <span>this.data = configData;
    </span>  <span>}
    </span>
      <span>// This method will be called when the class
    </span>  <span>// is restored by Atom.
    </span>  <span>static deserialize (config) {
    </span>    <span>return new FancyComponent(config);
    </span>  <span>}
    </span>
      <span>// The returned object will be used to restore
    </span>  <span>// or save your data by Atom.
    </span>  <span>// The "deserializer" key must be the name of your class.
    </span>  <span>serialize () {
    </span>    <span>return {
    </span>      <span>deserializer: 'FancyComponent',
    </span>      <span>data: this.data
    </span>    <span>};
    </span>  <span>}
    </span>
      <span>doSomethingWithData () {}
    </span><span>}
    </span>
    <span>// Add class to Atom's deserialization system
    </span>atom<span>.deserializers.add(FancyComponent);
    </span>
    <span>export default FancyComponent;
    </span>
    登录后复制
    登录后复制
    >使用keymaps,您为软件包命令定义快捷方式。它们与特定范围绑定,其中范围是诸如Atom-Text-编辑器,Atom-Text-编辑器:NOT([mini])或Atom-workspace之类的CSS选择器。当匹配选择器的元素焦点并使用击键模式时,发出了您的自定义操作。

    >

    请记住,这些命令必须已在您的入口点中注册(atom.commands.add())。

    > 使用Chrome Developer Tools进行调试

    <span>// lib/main.js
    </span><span>import <span>FancyComponent</span> from './fancy-component';
    </span><span>import <span>SomeView</span> from './some-view';
    </span>
    <span>const YourPackage = {
    </span>  <span>fancyComponent: null,
    </span>  <span>someView: null,
    </span>
      <span>activate (state) {
    </span>    <span>// If the component has been saved at a previous session of Atom,
    </span>    <span>// it will be restored from the deserialization system. It calls your
    </span>    <span>// your components static 'deserialize()' method.
    </span>    <span>if (state.fancy) {
    </span>      <span>this.fancyComponent = atom.deserializers.deserialize(state.fancy);
    </span>    <span>}
    </span>    <span>else {
    </span>      <span>this.fancyComponent = new FancyComponent({ otherData: 'will be used instead' });
    </span>    <span>}
    </span>
        <span>// More activation logic.
    </span>  <span>},
    </span>
      <span>// As well as your component, your package has a serialize method
    </span>  <span>// to save the current state.
    </span>  <span>serialize () {
    </span>    <span>return {
    </span>      <span>fancy: this.fancyComponent.serialize(),
    </span>      <span>view: this.someView.serialize()
    </span>    <span>};
    </span>  <span>}
    </span><span>};
    </span>
    登录后复制
    登录后复制
    在原子中调试与在网络上调试没有什么不同。您可以在View>“开发人员”下激活Chrome Developer工具>切换开发人员工具以查看丢弃的错误,从代码中登录或了解Atom的标记。

    >

    用茉莉

    进行单位测试 原子使用茉莉框架进行测试。测试放置在规格/顶级目录中,并且必须以-spec(例如花式component-spec.js)结束文件。不需要测试或发布包裹,但是它们是备份代码质量并确保添加新功能时没有破坏的好方法。

    >

    要运行测试,您可以使用窗口:Run-Package-Specs命令或转到View>“开发人员”> Run Package Specs。 如何使用香草JavaScript编写原子包装如果您想在Travis CI上运行软件包规格,则在Atom的博客上有一个简短的文章,涉及如何设置它。

    软件包流量

    这是很多输入。原子的实际流量或执行顺序大致如下(注意:测试不是软件包流的一部分)。

      Atom启动并阅读您的软件包。
      • 菜单,keymaps,样式表和所有其他配置
      • 如果定义了激活程序,则将运行
      • >
    1. 主入口点(即激活())执行
      • >您的软件包魔术(例如,对用户输入做出反应,创建视图,修改文件)
      >您将包裹停用或关闭原子
    2. 原子序列化包装状态
      结论
    >希望我的文章能帮助您对Atom软件包开发有基本的了解。仍然有更多功能和许多主题,不幸的是,仅一篇文章就无法涵盖。看看Atom飞行手册以查看其他可能的可能。

    您将开发哪个包装?

    >

    使用香草JavaScript编写原子软件包的经常询问问题(常见问题解答)

    什么是香草javaScript,为什么在编写原子包中它很重要?这在编写原子软件包方面很重要,因为它允许使用轻巧,高效且高度可定制的代码。使用Vanilla JavaScript,开发人员可以创建更快,更安全且更易于调试和维护的软件包。它还确保包装不依赖任何第三方库,从而使它们更可靠,更健壮。使用香草JavaScript的Atom软件包,您首先需要设置开发环境。这包括安装Node.js和Atom。安装了这些安装后,您可以使用Atom软件包生成器创建一个新软件包。之后,您可以使用香草JavaScript开始编写软件包。请记住要遵循原子包指南,以确保您的软件包与Atom编辑器兼容。

    //在module.js

    中导出一个函数,导出函数myfunction(){// function code eke

    >}

    //导入导入来自'./ module.js';

    >如何调试用Vanilla Javascript编写的原子软件包?

    atom提供一个内置的开发人员工具面板您可以用来调试包裹。您可以通过查看>开发人员>切换开发人员工具来打开此面板。在这里,您可以检查代码,设置断点,并监视变量和网络活动。此外,您可以在代码中使用Console.log()语句将其输出值以调试目的输出值。

    >

    >如何使我的原子包与不同版本的原子兼容?为了确保您的原子包与不同版本的原子兼容,您应该遵循原子API指南,避免使用不推荐使用的API。您还应该在不同版本的原子上测试包装,以识别和解决任何兼容性问题。此外,您可以在软件包的包装文件中指定最低所需的原子版。可以使用APM Publish命令将其发布到Atom软件包存储库。在发布之前,您需要使用APM版本命令创建软件包的新版本。您还需要为您的软件包创建一个GitHub存储库,然后将代码推向其。

    我可以在用Vanilla Javascript编写的Atom软件包中使用ES6功能吗? ATOM包中的ES6功能。 Atom的基础node.js运行时间支持大多数ES6功能,包括let and and const声明,箭头功能,模板文字等。但是,您应该确保使用ES6功能不会引起与旧版本的Atom的兼容性问题。

    >如何处理用Vanilla JavaScript编写的Atom软件包中的错误?这使您可以捕获和处理在执行代码期间可能发生的异常。您也可以使用Atom.Notifications API向用户显示错误消息。此API提供了显示不同类型的通知的方法,包括错误通知。

    >

以上是如何使用香草JavaScript编写原子包装的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板