官术网_书友最值得收藏!

Setting up the project

We will quickly set up the project before we can start writing. We will use npm to manage our dependencies and gulp to build our project. These tools are built on NodeJS, so it should be installed from nodejs.org.

First of all, we must create a new directory in which we will place all files. We must create a package.json file used by npm:

{ 
  "name": "weather-widget", 
  "version": "1.0.0", 
  "private": true, 
  "description": "" 
} 

The package.json file contains information about the project, such as the name, version, and a description. These fields are used by npm when you publish a project on the registry on NPM, which contains a lot of open source projects. We will not publish it there. We set the private field to true, so we cannot accidentally publish it.

Directory structure

We will separate the TypeScript sources from the other files. The TypeScript files will be added in the lib directory. Static files, such as HTML and CSS, will be located in the static directory. This directory can be uploaded to a webserver. The compiled sources will be written to static/scripts. We first install Angular and some requirements of Angular with npm. In a terminal, we run the following command in the root directory of the project:

npm install angular2 rxjs es6-shim reflect-metadata zone.js --save

The console might show some warnings about unmet peer dependencies. These will probably be caused by a minor version mismatch between Angular and one of its dependencies. You can ignore these warnings.

Configuring TypeScript

TypeScript can be configured using a tsconfig.json file. We will place that file in the lib directory, as all our files are located there. We specify the experimentalDecorators and emitDecoratorMetadata options, as these are necessary for Angular:

{ 
  "compilerOptions": { 
    "target": "es5", 
    "module": "commonjs", 
    "experimentalDecorators": true, 
    "emitDecoratorMetadata": true, 
    "lib": ["es2015", "dom"] 
  } 
} 

The target option specifies the version of JavaScript of the generated code. Current browsers support es5. TypeScript will compile newer JavaScript features, such as classes, to an es5 equivalent. With the lib option, we can specify the version of the JavaScript library. We use the libraries from es2015, the version after es5. Since these libraries might not be available in all browsers, we will add a polyfill for these features later on. We also include the libraries for the DOM, which contains functions such as document.createElement and document.getElementById.

Building the system

With gulp, it is easy to compile a program in multiple steps. For most webapps, multiple steps are needed: compiling TypeScript, bundling modules, and finally minifying all code. In this application, we need to do all of these steps.

Gulp streams source files through a series of plugins. These plugins can (just like gulp itself) be installed using npm:

npm install gulp --global
npm install gulp gulp-typescript gulp-sourcemaps gulp-uglify small --save-dev

Tip

The --global flag will install the dependency globally such that you can call gulp from a terminal. The --save-dev flag will add the dependency to the devDependencies (development dependencies) section of the package.json file. Use --save to add a runtime dependency.

We use the following plugins for gulp:

  • The gulp-typescript plugin compiles TypeScript to JavaScript
  • The gulp-uglify plugin can minify JavaScript files
  • The small plugin can bundle external modules
  • The gulp-sourcemaps plugin improves the debugging experience with source maps

We will create two tasks, one that compiles the sources to a development build and another that can create a release build. The development build will have source maps and will not be minified, whereas the release build will be minified without source maps. Minifying takes some time so we do not do that on the debug task. Creating source maps in the release task is possible too, but generating the source map is slow so we will not do that.

We write these tasks in gulpfile.js in the root of the project. The second task is the easiest to write, as it only uses one plugin. The task will look like this:

var gulp = require('gulp'); 
var uglify = require('gulp-uglify'); 
 
gulp.task('release', ['compile'], function() { 
  return gulp.src('static/scripts/scripts.js') 
    .pipe(uglify()) 
    .pipe(gulp.dest('static/scripts')); 
}); 

The gulp.task call will register a task named release, which will take static/scripts/scripts.js (which will be created by the compile task), run uglify (a tool that minifies JavaScript) on it, and then save it in the same directory again. This task depends on the compile task, meaning that the compile task will be run before this one.

The first task, compile, is more complicated. The task will transpile TypeScript, and bundle the files with the external libraries.

First, we must load some plugins:

var gulp = require('gulp');

var typescript = require('gulp-typescript');
var small = require('small').gulp;
var sourcemaps = require('gulp-sourcemaps');  

var uglify = require('gulp-uglify'); 

We load the configuration of TypeScript in the tsconfig.json file:

var tsProject = typescript.createProject('lib/tsconfig.json');

Now, we can finally write the task. First, we load all sources and compile them using the TypeScript compiler. After that, we bundle these files (including Angular, stored under node_modules, using small):

gulp.task('compile', function() { return gulp.src('lib/**/*.ts') .pipe(sourcemaps.init()) .pipe(typescript(tsProject)) .pipe(small('index.js', { externalResolve: ['node_modules'], globalModules: { "crypto": { standalone: "undefined" } } })) .pipe(sourcemaps.write('.')) .pipe(gulp.dest('static/scripts')); });
gulp.task('release', ['compile'], function() {
   return gulp.src('static/scripts/scripts.js')
         .pipe(uglify())
         .pipe(gulp.dest('static/scripts'));
});

gulp.task('default', ['compile']);

This task compiles our project and saves the result as static/scripts/scripts.js. The sourcemaps.init() and sourcemaps.write('.') functions handle the creation of source maps, which will improve the debugging experience.

The HTML file

The main file of our application is the HTML file, static/index.html. This file will reference our (compiled) scripts and stylesheet:

<!DOCTYPE HTML> 
<html> 
  <head> 
    <title>Weather</title> 
    <link rel="stylesheet" href="style.css" /> 
  </head> 
  <body> 
    <div id="wrapper"> 
      <weather-widget>Loading..</weather-widget> 
    </div> 
    <script src="scripts/index.js" type="text/javascript"></script> 
  </body> 
</html> 

The weather-widget tag will be initialized by Angular. We will add some fancy styles in static/style.css:

body { 
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; 
  font-weight: 100; 
} 
h1, h2, h3 { 
  font-weight: 100; 
  margin: 0; 
  padding: 0; 
  color: #57BEDE; 
} 
#wrapper { 
  position: absolute; 
  left: 0; 
  right: 0; 
  top: 0; 
  width: 450px; 
  margin: 10% auto; 
} 
a:link, a:visited { 
  color: #57BEDE; 
  text-decoration: underline; 
} 
a:hover, a:active { 
  color: #44A4C2; 
}  
.clearfix { 
  clear: both; 
} 
主站蜘蛛池模板: 兴安县| 黑山县| 鄱阳县| 丁青县| 蒲江县| 沂源县| 康保县| 吴旗县| 奉贤区| 盈江县| 铁力市| 泸水县| 大厂| 龙泉市| 昂仁县| 徐汇区| 廉江市| 怀仁县| 张家界市| 祁连县| 探索| 上栗县| 澄江县| 五家渠市| 龙南县| 菏泽市| 宜城市| 虞城县| 霍山县| 四平市| 巨野县| 宁乡县| 寻乌县| 泽州县| 曲松县| 新郑市| 灌云县| 兴和县| 堆龙德庆县| 绥江县| 洛宁县|