Merge pull request #239 from atom/tutorials

Improve the tutorials
This commit is contained in:
Cheng Zhao 2014-05-04 18:32:56 +08:00
commit 8a8048a629
7 changed files with 247 additions and 178 deletions

View file

@ -1,9 +1,10 @@
# Atom-Shell Documentations # Atom-Shell Documentations
## Guides ## Tutorials
* [Quick start](quick-start.md) * [Quick start](tutorial/quick-start.md)
* [Use native modules](use-native-modules.md) * [Application distribution](tutorial/application-distribution.md)
* [Use native node modules](tutorial/use-native-node-modules.md)
## Development ## Development

View file

@ -113,14 +113,8 @@ window.onbeforeunload = function(e) {
### Event: 'closed' ### Event: 'closed'
Emitted when the window is closed. At the time of this event, window is not Emitted when the window is closed. After you have received this event you should
destroyed yet so you can still do some operations to the window (but you remove the reference to the window and avoid using it anymore.
shouldn't!).
### Event: 'destroyed'
Emitted when the memory taken by the native window is released. Usually you
should dereference the javascript object when received this event.
### Event: 'unresponsive' ### Event: 'unresponsive'
@ -159,12 +153,11 @@ Get the `WebContents` of devtools of this window.
### BrowserWindow.destroy() ### BrowserWindow.destroy()
Destroy the window and free the memory without closing it. Force closing the window, the `unload` and `beforeunload` event won't be emitted
for the web page, and `close` event would also not be emitted for this window,
but it would gurrantee the `closed` event to be emitted.
**Note:** Usually you should always call `Window.close()` to close the window, You should only use this method when the web page has crashed.
**which will emit `beforeunload` and `unload` events for DOM. Only use
**`Window.destroy()` when the window gets into a very bad state and you want
**to force closing it.
### BrowserWindow.close() ### BrowserWindow.close()

View file

@ -1,120 +0,0 @@
# Quick start
## Introduction
Generally, atom-shell lets you create a web-based desktop application in pure
javascript. Unlike CEF, which requires you to use C++ to write underlying
code, or node-webkit, which only allows you to write everything in the web
page, atom-shell gives you the power to use javascript to control the browser
side.
## Browser and renderer
Atom-shell is built upon Chromium's Content API, so it has the same
multi-processes architecture with the Chrome browser. In summary, things about
UI are done in the browser process, and each web page instance would start a
new renderer process.
In atom-shell, you can just put everything in a simpler way: when you are
executing javascript in browser side, you can control the application's life,
create UI widget, deal with system events, and create windows which contain
web pages; while on the renderer side, you can only control the web page you
are showing, if you want something more like creating a new window, you should
use IPC API to tell the browser to do that.
## The architecture of an app
Generally, an app of atom-shell should contains at least following files:
```text
app/
├── package.json
├── main.js
└── index.html
```
The format of `package.json` is exactly the same with node's modules, and the
script specified by the `main` field is the startup script of your app, which
will run under the browser side. An example of your `package.json` is like
this:
```json
{
"name" : "atom",
"version" : "0.1.0",
"main" : "main.js"
}
```
The `main.js` will be executed, and in which you should do the initialization
work. To give the developers more power, atom-shell works by exposing
necessary Content APIs in javascript, so developers can precisely control
every piece of the app. An example of `main.js` is:
```javascript
var app = require('app'); // Module to control application life.
var Window = require('window'); // Module to create native browser window.
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.
var mainWindow = null;
// Quit when all windows are closed.
app.on('window-all-closed', function() {
app.terminate();
});
// This method will be called when atom-shell has done everything
// initialization and ready for creating browser windows.
app.on('ready', function() {
// Create the browser window,
mainWindow = new Window({ width: 800, height: 600 });
// and load the index.html of the app.
mainWindow.loadUrl('file://' + __dirname + '/index.html');
// Catch the event when web page in the window changes its title.
mainWindow.on('page-title-updated', function(event, title) {
// Prevent the default behaviour of 'page-title-updated' event.
event.preventDefault();
// Add a prefix for the window's original title.
this.setTitle('Atom Shell - ' + title);
});
// Hook to when the window is closed.
mainWindow.on('closed', function() {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null;
});
});
```
Finally the `index.html` is the web page you want to show, in fact you
actually don't need to provide it, you can just make the window load url of a
remote page.
## Package your app in atom-shell
To make atom-shell run your app, you should name the folder of your app as
`app`, and put it under `Atom.app/Contents/Resources/`, like this:
```text
Atom.app/Contents/Resources/app/
├── package.json
├── main.js
└── index.html
```
Then atom-shell will automatically read your `package.json`. If there is no
`Atom.app/Contents/Resources/app/`, atom-shell will load the default empty
app, which is `Atom.app/Contents/Resources/browser/default_app/`.
## IPC between browser and renderer
Atom-shell provides a set of javascript APIs for developers to communicate
between browser and renderers. There are two types of message: asynchronous
messages and synchronous messages, the former one is quite similar with node's
IPC APIs, while the latter one is mainly used for implement the RPC API.
Details can be found in the `ipc` module reference.

View file

@ -0,0 +1,34 @@
# Application distribution
To distribute your app with atom-shell, you should name the folder of your app
as `app`, and put it under atom-shell's resources directory (on OS X it is
`Atom.app/Contents/Resources/`, and on Linux and Windows it is `resources/`),
like this:
On Mac OS X:
```text
atom-shell/Atom.app/Contents/Resources/app/
├── package.json
├── main.js
└── index.html
```
On Windows and Linux:
```text
atom-shell/resources/app
├── package.json
├── main.js
└── index.html
```
Then execute `Atom.app` (or `atom` on Linux, and `atom.exe` on Window), and
atom-shell will start as your app. The `atom-shell` directory would then be
your distribution that should be delivered to final users.
## Build with grunt
If you build your application with `grunt`, then there is a grunt task that can
download atom-shell for current platform automatically:
[grunt-download-atom-shell](https://github.com/atom/grunt-download-atom-shell).

View file

@ -0,0 +1,147 @@
# Quick start
## Introduction
Generally, atom-shell enables you to create desktop applications with pure
JavaScript by providing a runtime with rich native APIs, you could see it as
an variant of node.js runtime that focused on desktop applications instead of
web server.
But it doesn't mean atom-shell is a JavaScript binding to GUI libraries, instead
atom-shell uses web pages as GUI, so you could also see it as a minimal Chromium
browser, controlled by JavaScript.
### The browser side
If you had experience with node.js web applications, you would notice that there
are types of JavaScript scripts: the server side scripts and the client side
scripts. The server side JavaScript, is the scrips that run on the node.js
runtime, and the client side JavaScript, is the ones that run on user's browser.
In atom-shell we have similar concepts, since atom-shell displays GUI by showing
web pages, we would have scripts that run in the web page, and also have scripts
ran by the atom-shell runtime, which created those web pages. Like node.js, we
call the former ones client client scripts, and the latter one browser side
scripts.
In traditional node.js applications, communication between server side and
client side are usually done by web sockets. In atom-shell, we have provided
the [ipc](../api/renderer/ipc-renderer.md) module for browser side to client
communication, and the [remote](../api/renderer/remote.md) module for easy RPC
support.
### Web page and node.js
Normal web pages are designed to not touch outside world, which makes them not
suitable for interacting with native systems, atom-shell provides node.js APIs
in web pages so you could access native resources in web pages, just like
[node-webkit](https://github.com/rogerwang/node-webkit).
But unlike node-webkit, you could not do native GUI related operations in web
pages, instead you need to do them on the browser side by sending messages or
use the easy [remote](../api/renderer/remote.md) module.
## Write your first atom-shell app
Generally, an atom-shell app would be like this:
```text
app/
├── package.json
├── main.js
└── index.html
```
The format of `package.json` is exactly the same with node's modules, and the
script specified by the `main` field is the startup script of your app, which
will run under the browser side. An example of your `package.json` is like
this:
```json
{
"name" : "your-app",
"version" : "0.1.0",
"main" : "main.js"
}
```
The `main.js` should create windows and handle system events, and an typical
example is:
```javascript
var app = require('app'); // Module to control application life.
var BrowserWindow = require('browser-window'); // Module to create native browser window.
// Report crashes to our server.
require('crash-reporter').start();
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the javascript object is GCed.
var mainWindow = null;
// Quit when all windows are closed.
app.on('window-all-closed', function() {
if (process.platform != 'darwin')
app.quit();
});
// This method will be called when atom-shell has done everything
// initialization and ready for creating browser windows.
app.on('ready', function() {
// Create the browser window.
mainWindow = new BrowserWindow({width: 800, height: 600});
// and load the index.html of the app.
mainWindow.loadUrl('file://' + __dirname + '/index.html');
// Emitted when the window is closed.
mainWindow.on('closed', function() {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
mainWindow = null;
});
});
```
Finally the `index.html` is the web page you want to show:
```html
<!DOCTYPE html>
<html>
<head>
<title>Hello World!</title>
</head>
<body>
<h1>Hello World!</h1>
We are using node.js <script>document.write(process.version)</script>
and atom-shell <script>document.write(process.versions['atom-shell'])</script>.
</body>
</html>
```
## Run your app
After done writing your app, you could create a distribution of your app by
following the [Application distribution](./application-distribution.md) guide
and then execute the packaged app, or you can just use the downloaded atom-shell
binary to execute your app directly.
On Window:
```cmd
$ .\atom-shell\atom.exe app
```
On Linux:
```bash
$ ./atom-shell/atom app
```
On Mac OS X:
```bash
$ ./Atom.app/Contents/MacOS/Atom app
```

View file

@ -0,0 +1,56 @@
# Use native node modules
The native node modules are supported by atom-shell, but since atom-shell is
using a different V8 version from official node, you need to use `apm` instead
of `npm` to install node modules.
The usage of [apm](https://github.com/atom/apm) is quite similar to `npm`, to
install dependencies from `package.json` of current project, just do:
```bash
$ cd /path/to/atom-shell/project/
$ apm install .
```
But you should notice that `apm install module` wont' work because it will
install a user package for [Atom Editor](https://github.com/atom/atom) instead.
## Native node module compability
Since node v0.11.x, there were vital changes of V8 API, so generally all native
modules written for node v0.10.x wouldn't work for node v0.11.x, and since
atom-shell internally uses node v0.11.9, it carries with the same problem.
To solve it, you should use modules that support both node v0.10.x and v0.11.x,
and [many modules](https://www.npmjs.org/browse/depended/nan) do support the
both now. For old modules that only support node v0.10.x, you should use the
[nan](https://github.com/rvagg/nan) module to port it to v0.11.x.
## Other ways of installing native modules
Apart from `apm`, you can also use `node-gyp` and `npm` to manually build the
native modules.
### The node-gyp way
First you need to check which node release atom-shell is carrying via
`process.version` (at the time of writing it is v0.10.5), then you can
configure and build native modules via following commands:
```bash
$ cd /path-to-module/
$ HOME=~/.atom-shell-gyp node-gyp rebuild --target=0.10.5 --arch=ia32 --dist-url=https://gh-contractor-zcbenz.s3.amazonaws.com/atom-shell/dist
```
The `HOME=~/.atom-shell-gyp` changes where to find development headers. The
`--target=0.10.5` is specifying node's version. The `--dist-url=...` specifies
where to download the headers.
### The npm way
```bash
export npm_config_disturl=https://gh-contractor-zcbenz.s3.amazonaws.com/atom-shell/dist
export npm_config_target=0.10.5
export npm_config_arch=ia32
HOME=~/.atom-shell-gyp npm install module-name
```

View file

@ -1,42 +0,0 @@
# Use native modules
Since atom-shell is using a different V8 version from the official node, you
need to build native module against atom-shell's headers to use them.
The [apm](https://github.com/atom/apm) provided a easy way to do this, after
installing it you could use it to install dependencies just like using `npm`:
```bash
$ cd /path/to/atom-shell/project/
$ apm install .
```
But you should notice that `apm install module` wont' work because it will
install a user package for [Atom](https://github.com/atom/atom) instead.
Apart from `apm`, you can also use `node-gyp` and `npm` to manually build the
native modules.
## The node-gyp way
First you need to check which node release atom-shell is carrying via
`process.version` (at the time of writing it is v0.10.5), then you can
configure and build native modules via following commands:
```bash
$ cd /path-to-module/
$ HOME=~/.atom-shell-gyp node-gyp rebuild --target=0.10.5 --arch=ia32 --dist-url=https://gh-contractor-zcbenz.s3.amazonaws.com/atom-shell/dist
```
The `HOME=~/.atom-shell-gyp` changes where to find development headers. The
`--target=0.10.5` is specifying node's version. The `--dist-url=...` specifies
where to download the headers.
## The npm way
```bash
export npm_config_disturl=https://gh-contractor-zcbenz.s3.amazonaws.com/atom-shell/dist
export npm_config_target=0.10.5
export npm_config_arch=ia32
HOME=~/.atom-shell-gyp npm install module-name
```