目录:

如果你对GmailAssist感兴趣,可以在chrome商店中搜索“Gmail助手”,或点击这里直接访问商店来安装试用;
如果你对GmailAssist的源码感兴趣,可以在我的GitHub上查看它的源码。


一个Chrome扩展包括一系列文件,HTML文件、CSS样式文件、JavaScript脚本、图片等,以及一个最有特点的manifest.json。

1. manifest.json是啥

它是每个chrome扩展有且只有一个的清单文件,它指明了该扩展的基本信息,如名称、版本、需要的权限等等,格式是json。

JSON

  JSON是一种独立于语言和平台的数据格式,JSON对象就是一种格式化的静态的数据,接下来的chrome扩展中各模块之间交换信息就是用这种格式。传送时就是作为简单的字符串来传,js在收到json数据的时候可以看成对象来解析,其中可以有层次。其实不仅chrome扩展模块之间的数据交流可以用这种格式,跨应用跨平台的数据交流也可以用这种格式,因为它的数据冗余度很小,并且可读性很好,也容易解析(在我前面的介绍中“JSON”和“json”都有,因为这个大小写是无所谓的,指的都是同一个东西)。下面的manifest.json就可以作为一个例子。
而*.json格式的文件,其内容就是一个json对象。manifest.json就是用这样一种格式化的方法来指明了一个chrome扩展的基本信息。

manifest.json

直接举例来说吧,GmailAssist的manifest.json的部分内容如下:

{
"manifest_version": 2,
"name": "Gmail邮箱附件处理助手",
"version": "1.9",
"default_locale": "en",
"description": "查询邮箱内全部附件,支持批量下载,支持批量添加至最新的草稿。要开始使用,在登录Gmail后,点击地址栏右端图标,选择“授权”即可。",
"icons": {
"48": "images/icon48.png",
"128": "images/icon128.png"
},
"short_name": "GmailAssist",
"page_action": {
"default_icon": {
"19": "images/icon19.png",
"38": "images/icon38.png"
},
"default_title" : "__MSG_extName__",
"default_popup": "popup.html"
},
"background": {
"scripts": ["background.js"],
"persistent": false
},
"content_scripts": [
{
"js": ["oauth2/oauth2_inject.js"],
"matches": [ "http://www.google.com/robots.txt*"],
"run_at": "document_start"
},
{...}
],
... }

  首先,作为我们理解json格式的例子,上面这段被'{'和'}'括起来的,就是一个json对象。说白了一个json对象就是一个结构体,其中有各个字段,不同字段之间用逗号隔开,最后一个字段后面不需要逗号。每个字段都是“key:value”这样的形式,每个“key”就可以理解为这个结构体的一个属性,一个具体的属性必然有一个具体的值。(不同于C语言的struct,这里你不需要提前声明一个结构体内有哪些属性,也不需要为每个属性指定其类型,如C语言的int、char等,其类型会在js中解析时自动判断。而类似于C语言中struct的声明的“内容模板”,是不需要你操心的,仅就manifest.json而言,chrome已经定义好了一套“模板”,你在写你的manifest时,按chrome要求的规范来就可以)

  json对象中可以包含多个并列的字段(属性),每个属性的值可以是这几种类型中的一个:字符串、数字、对象、数组、布尔null。字符串就是一串字符直接拿双引号("")括起来(比如例子中的name属性的值"Gmail邮箱附件处理助手"),数字就是不带引号(如例子中manifest_version的值2),数组就是用'['、']'括起来的一个或多个元素(这个元素就可以是上面说的字符串、数字、对象、数组等中的一个,当然了,一个数组内的元素们必须是同种类型),布尔就是true、false(不加引号)。每种类型都可以在上面的例子中找到对应的实例。

  你的扩展程序在发布和安装的时候,chrome商店和chrome都会检查manifest.json,从中获取必要的信息,并且检查你写的是否合法(例如,如果你的popup.html中有内嵌的js脚本,而你的"content_security_policy"字段是空,你在试图让chrome加载你的扩展程序时,它就会提示错误。这些现在不懂没关系,目前还不重要,有个大概的印象就行,到后面自然会明白)。所谓的必要信息,不仅是一些给人看的信息(如扩展的名称、简称、简介等),还有给浏览器看的信息(如content_script、page_action等字段),后者通知了chrome你的程序的入口等程序运行相关的信息。

具体来说有几个常用字段:
有三个属性是必须的:name, version, manifest_version。
1、"name": 你的扩展程序的名称;
字符串,可以包括中文。这里补充说一点,manifest.json需要按UTF-8编码格式来保存,否则在加载到浏览器中时会报错。
2、"version": 指你的扩展程序的版本号;
字符串,注意虽然版本号一般都是一串数,但它应该是用字符串来表示,而不是数字,所以别忘了引号。版本号最多可以是用3个.分隔的4个数,比如"1.0.0.16"。
3、"manifest_version": 指定清单文件格式的版本(数字);
在Chrome18之后(在chrome中打开chrome://help即可查看当前你的chrome版本),应该都是2,所以直接写2即可。

其他常用字段,我这里只介绍GmailAssist中涉及的,完整的介绍可以参考google官方的文档。另外多说一点,容易百度到,360有一份汉化的chrome扩展开发文档,但我记得这份文档并不太完整,而且翻译质量不是太高,读着比较费劲。为了方便,还是去看google官方的文档吧,毕竟技术人员写的文档,没什么难懂的长难句的,很好读,而且翻译总难免有一些不确切的地方,看官方的文档还是比较保险。(再多说一句,可能新手在翻墙上还会有障碍,推荐一个傻瓜式的小工具,蓝灯(Lantern),效果非常好自行百度下载吧)

"default_locale": 这个是指定你的扩展的默认显示的语言,涉及国际化内容,后面会介绍;
"description": 你的扩展的描述,它是显示在chrome应用商店中和chrome扩展页面的,如下图。(其中,商店中显示的应该是你在manifest中通过default_locale指定的默认语言,我这里指定的是英文)

(补充:设置浏览器语言可以通过:1.打开chrome的设置页;2.往下拉找到“显示高级设置...”,点它;3.再往下拉找到“语言”-“语言和输入设置”,点它;4.点左下角的添加,选择你要的语言并确定;5.在左侧列表中点你要的语言,在右侧点“以这种语言显示Google Chrome”;6.重启Chrome)
  "description"中还有"icons"字段,它指定你的扩展程序的图标,数字表明分辨率(如128表示图片分辨率为128*128像素)。

"short_name":你的扩展的简称,这个可有可无。
"page_action": 与之平级的还有另一个字段"browser_action",你的manifest中最多出现二者之一。直观地来说,这俩属性分别指明你的扩展在特定网页中才能用,还是打开浏览器后一直能用。更直观的就是,你的扩展的图标出现的位置不同,如下图。

  图中是地址栏的最右端,显然地址栏里外各有几个图标。地址栏里的对应的就是指定了page_action的扩展(如GmailAssist),地址栏外的对应的就是指定了browser_action了的。开发时,根据你的需要决定用哪个,并在manifest中指定page_action或browser_action即可。因为GmailAssist是针对Gmail的,所以应该让它在用户在浏览Gmail邮箱时可用,其他时候就直接匿了就行,因此咱们选择page_action。(browser_action和page_action是差不多的,具体细节可以看谷歌的文档)
  注意到page_action中有几个字段:
"default_icon"指定你的扩展在地址栏中显示的图标,和前面的description中的icons类似,数字指明分辨率。与description中的icons不同之处在于,后者是指定了在chrome的扩展管理页面(chrome://extension)等处显示的图标,而前者是仅仅指地址栏内的图标。Chrome默认选择19像素的图片,对retina屏显示38像素的。这几个图标不是所有的分辨率都需要各自指定一张图片,但为了保证显示效果,最好是把我这里涉及的几种大小都准备一张图片。如果你不指定自己的图标,也是可以的,chrome会显示一个默认图标。如果你需要图标动态变化,可以参考setIcon(https://developer.chrome.com/extensions/browserAction#method-setIcon)或badge(和setIcon在同一个页面中介绍的)。
"default_title" 是当你鼠标悬停在地址栏中的图标上时,显示的说明文字。
"default_popup" 是你点击扩展图标时,在图标下面弹出的小窗口,如下图是GmailAssist的popup页面。

下面将要提到的几个属性,这里只是暂时进行概念的简单介绍,估计新手很难一下子理解,没关系,有个印象就行,后面我会分别具体说明。
"background": 你的扩展如果需要什么在后台持续运行的部分,就可以通过这个字段来指出。不仅是js,你还可以指定一个自己编写的html,像这样:

"background": {
"page": "background.html",
"scripts": ["background.js"],
"persistent": false
}

  如果仅仅指定js,chrome会自己生成一个html来在后台跑你指定的脚本;当然如果指定了你自己写的html,它也不会显示出来。
"persistent"值默认为true。为true时,你在background字段中指出的js脚本(注意格式是数组,因而可以有多个脚本)将持续运行在后台,而若persistent为false,则这些脚本将只在事件活动时运行,事件不活动时就会释放其占有的内存等资源。

"content_scripts": 这个属性的内容是一个对象数组,数组内每个对象都指明一系列js脚本及其将要注入的页面(支持通配符*),以及注入时机(可以为"document_start"、"document_end" 或 "document_idle",默认为 "document_idle")。
说明一下,这里的脚本是注入到你要操作DOM的页面的,但这个注入,并不同于在页面中直接写一条引入外部脚本语句。直接在页面中引入的多个js之间是共享命名空间的,但content_script与它们之间是独立的,content_script和页面原有js仅共享页面的DOM元素。在GmailAssist开发初期,这个地方给我带来了一些麻烦,后面我会细说。

暂时介绍这么多字段,这些可以说是最常用的,其他的还有一些很常用,如"permission"等,GmailAssist中涉及的,我会在后面慢慢介绍;而GmailAssist中未涉及的,请参考谷歌的文档。

2. 国际化(多语言支持)相关的文件

  在支持多语言的扩展中,除了开头提到的HTML、CSS、js等文件,还会有一个文件夹"_locales",其结构如图:
  其中有en, zh两个文件夹,表明GmailAssist分别有英文、中文两个版本。两个文件夹下各有一个文件,叫"messages.json"(两个文件夹中的文件都是这个名字),其中格式化地记录着你的插件将要用到的不同语言版本的各个字符串,例如:细心的话,你可能注意到在上面的manifest.json中"page_action"字段下有个"default_title",其值为"__MSG_extName__"。前面说过,这个字段说明了你鼠标放在图标上会浮出的文字。这个部分就是用了国际化(i18n)的处理,针对不同的语言,这个浮出的文字将显示不同的内容。具体到这个例子上,在_locales->zh文件夹下的messages.json中,就有这样一段:

{
"extName":{
"message":"Gmail附件助手"
},
...
}

同样的,在_locales->en文件夹下的messages.json中,有这样一段:

{
"extName":{
"message":"Gmail Attachment Manager"
},
...
}

  注意到"extName"就正对应着"__MSG_extName__",在插件运行时,chrome就会把"__MSG_extName__",根据当前用户浏览器设置的语言,去插件中_locales文件夹下去找当前语言对应的messages.json,并从中找到"extName"对应的字段,把这个字段中的message属性的值取出,替换掉"__MSG_extName__"。
  因此,在zh文件夹中的messages.json,在en文件夹中有一个所有字段key值相同但value值不同的副本。当然,也不要求所有的messages.json都有完整的各个字段名,当chrome去当前语言对应的文件中找不到需要的message内容时,它就会去默认语言的文件夹中找。例如,如果有对应zh-CN(简体中文)的一份messages.json,又有一份zh的,还有一份en的;当前用户浏览器的语言设置为zh-CN,插件manifest中声明的默认语言为en;但zh-CN和zh中的json文件里都没有"extName"字段,那么chrome在查找时会遵循zh-CN,zh,en这样的顺序,找到为止。
  messages.json中每个key都可以有另一个字段——"description",用于说明这个key的含义,这个字段是针对翻译人员的,如果你打算自己翻译,就可以不写这个字段。另外,chrome还要求,在manifest.json中声明default_locale字段,和在插件中设置_locales文件夹(即采用国际化)是充要的关系,即有一个就得有另一个,没有这个就不能有那个。
  国际化相关的内容,这里没有介绍完,还有一部分放在后面讲脚本时再介绍。

3. 其他的文件

  还有一些 *.html,*.css,*.js,都是写网页必然会接触的。复杂的高级特性可以暂时不去深入理解,但基本的语法是很容易掌握的,w3cschool的教程足够详尽,如果你是新手,完全可以花点时间先去学习一下这三者内容中基本的东西。

一个扩展的大体文件结构就是这样,下一篇介绍chrome扩展中的脚本是如何运行及通信的。
最后附上两个链接:
http://www.ituring.com.cn/minibook/950,这本书在我刚接触chrome extension的时候提供了非常大的帮助,讲解非常清晰,并且配有许多小例子帮助理解。
https://crxdoc-zh.appspot.com/extensions/getstarted,这是网上的个人翻译的chrome扩展及应用开发文档,我个人认为翻译质量比360那个文档要高,但我仍然建议你参考谷歌官方的英文文档,而只把这个作为辅助。

Chrome扩展开发之一——Chrome扩展的文件结构的更多相关文章

  1. Chrome扩展开发之三——Chrome扩展中的数据本地存储和下载

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

  2. 常见浏览器扩展开发笔记(chrome firefox 360 baidu qq sougou liebao uc opera)

    浏览器扩展开发貌似时下很冷门啊,但是不少企业还是有类似的应用,360的抢票插件啊,笔者最近在做的网页翻译扩展之类的.笔者在开发的过程中,遇到了不少坑,说是坑,说白了就是各个厂商支持的API不统一导致的 ...

  3. PHP扩展开发-简单类扩展

    今天来学习简单类扩展开发 实现目标为如下php的类 <?php class classext(){ private $username; CONST URL="http://www.g ...

  4. PHP扩展开发:第一个扩展

    在上一篇文章<PHP扩展开发:安装PHP>我们已经将开发PHP扩展的PHP环境安装成功,那么接下来采用最简单直接的方式创建第一个扩展. 我们先假设业务场景,是需要有这么一个扩展,提供一个叫 ...

  5. firefox扩展开发(一) : 扩展的基本结构

    用过firefox的人肯定要安装firefox的扩展,这样才能发挥火狐的全部实力.一般扩展是一个后缀为.xpi的文件,其实这个文件就是zip格式的压缩包,压缩了一个扩展所需要的所有目录和文件,基本的目 ...

  6. Chrome扩展开发之二——Chrome扩展中脚本的运行机制和通信方式

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

  7. Chrome扩展开发(Gmail附件管理助手)系列之〇——概述

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

  8. Chrome扩展开发之四——核心功能的实现思路

    目录: 0.Chrome扩展开发(Gmail附件管理助手)系列之〇——概述 1.Chrome扩展开发之一——Chrome扩展的文件结构 2.Chrome扩展开发之二——Chrome扩展中脚本的运行机制 ...

  9. PHP 扩展开发(将自己的一些代码封装成PHP扩展函数)

    今天时间不多,先给个地址,能搜到我这篇blog的朋友先看看我最近在看的一些文章.资料吧: 我的环境是 lnmp1.1 的 (LNMP一键安装包),所以要进行PHP扩展开发首先应该对环境配置和shell ...

随机推荐

  1. MTOM以及在WCF中的应用

    关于MTOM的基本概念 提到MTOM消息优化传输机制,通常的实验结果是使用MTOM传输数据会提高大约33%的性能. 消息传输优化机制 (MTOM) 标准允许将消息中包含的大型数据元素外部化,并将其作为 ...

  2. 集算器协助java处理多样性数据源之MongoDB

    MongoDB不支持join,其官网上推荐的unity jdbc可以把数据取出来进行二次计算实现join运算,但这些join.group.函数.表达式等高级功能都是收费版才有,而且即使是收费版本,对子 ...

  3. MySQL的诡异同步问题-重复执行一条relay-log

    MySQL的诡异同步问题 近期遇到一个诡异的MySQL同步问题,经过多方分析和定位后发现居然是由于备份引发的,非常的奇葩,特此记录一下整个问题的分析和定位过程. 现象 同事扩容的一台slave死活追不 ...

  4. 【VB超简单入门】一、写在前面

    每本书的前面总得写点什么,到我这里也自然不能免俗,前言这东西“存在即合理”,所以就随便写一点咯~ 首先这本书是给从未接触过编程的童鞋准备的,由于我学识疏浅,对VB也只是一知半解所以也只能讲一点点最基础 ...

  5. java String部分源码解析

    String类型的成员变量 /** String的属性值 */ private final char value[]; /** The offset is the first index of the ...

  6. Java zip and unzip demo

    目录结构如下: import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import ...

  7. 用c/c++混合编程方式为ios/android实现一个自绘日期选择控件(一)

    本文为原创,如有转载,请注明出处:http://www.cnblogs.com/jackybu 前言 章节: 1.需求描述以及c/c++实现日期和月历的基本操作 2.ios实现自绘日期选择控件 3.a ...

  8. codeforces 484B B. Maximum Value(二分)

    题目链接: B. Maximum Value time limit per test 1 second memory limit per test 256 megabytes input standa ...

  9. POJ 3416 Crossing --离线+树状数组

    题意: 给一些平面上的点,然后给一些查询(x,y),即以(x,y)为原点建立坐标系,一个人拿走第I,III象限的点,另一个人拿II,IV象限的,点不会在任何一个查询的坐标轴上,问每次两人的点数差为多少 ...

  10. Codeforces 369E Valera and Queries --树状数组+离线操作

    题意:给一些线段,然后给m个查询,每次查询都给出一些点,问有多少条线段包含这个点集中的一个或多个点 解法:直接离线以点为基准和以线段为基准都不好处理,“正难则反”,我们试着求有多少线段是不包含某个查询 ...