Saturday, February 18, 2017

WordPress

After my dabble in WordPress and Genesis Framework, I just wanted to point out this exceptionally cool tool if you run a Digitial Ocean server.

ServerPilot

They set up your server that way I would want to do it manually, but it's a bit of a pain in the ass. Why bother when these folks make it so easy and very fast.

Setting Up Angular 2 wo CLI

I saw this article this morning and it didn't work out quite right, so I thought I'd repost with some updates and links to solutions I found.

Create a Directory and move into it
mkdir anyname && cd anyname

Create a file
nano index.html

Add to index.html
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Angular 2 Manual Setup</title>
</head>
<body>
  <h2>App is Running</h2>
</body>
</html>

Any valid HTML template will do.

Install lite-server which is a mini web server
npm install lite-server

Initialize NPM
npm init

Add the following text to the package.json file generated by the line of code above.
"scripts": {
  "test": "echo \"Error: no test specified\" && exit 1",
  "lite": "lite-server"
}

There is already some code in the package.json file. Make sure you offset this new property and array with the proper punctuation.

package.json (Before)
{
  "name": "angular-scratch",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "author": "",
  "license": "ISC",
  "devDependencies": {
  }
}

package.json (After)
{
  "name": "angular-scratch",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "lite": "lite-server"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
  }
}

If you were to type  npm run lite  at the command prompt, the Node lite-server will start, but we're not ready for that just yet.

Install Typescript
npm install typescript --save-dev

Create a tsconfig.json file
nano tsconfig.json

Add the following JSON to tsconfig.json
{
  "compilerOptions": {
    "target": "es5",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": false
  }
}

Install these scoped NPM packages 
npm install @types/node @types/core-js @types/jasmine --save-dev

Finish setting up package.json
nano package.json

Update package.json thusly
{
  "start": "tsc && concurrently \"npm run tsc:w\" \"npm run lite\"",  
  "name": "angular-from-scratch",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "start": "concurrently \"npm run tsc:w\" \"npm run lite\"",
    "test": "echo \"Error: no test specified\" && exit 1",
    "lite": "lite-server",
    "tsc" : "npm run tsc",
    "tsc:w" : "npm run tsc -w"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
  }

}

A number of sites had  tsc && concurrently  but this appears to be wrong. It compiles correctly, but throws lots of errors about tsc and tsc:w. 

Install concurrently
npm install concurrently --save-dev

Concurrently allows you to run more than one npm operation at the same time.

Again, at this point, the site compiled correctly, but I still got errors in the command window. After some searching, I found this step.

Create an empty.ts file
nano empty.ts

Just leave it empty. The errors I was receiving concerned a lack of input. The empty.ts file satisfies that need. It should compile without errors now.

At this point, you don't have to install Angular. You could go any direction with typescript. If you wanted to, you could ignore the typescript steps above and just run straight HTML, JavaScript, and CSS with a nice watcher and auto-refresh. I'll verify that claim sometime soon.

Now you can type  npm run start  and both lite-server will start and Typescript (tsc) will run with "watching" turn on, so it refreshed your browser every time a project file gets updated.

Open the index.html file and make a change. Once saved, watch the browser as it refreshes and displays your updated HTML file.

Departure from the original article (Just webpack no systemjs)

Install RxJS, ZoneJS, CoreJS, Webpack and Webpack Dev Server
npm install zone.js core-js rxjs@5.0.3 webpack webpack-dev-server --save-dev

Install Webpack Loaders
npm install --save-dev angular2-template-loader awesome-typescript-loader css-loader file-loader html-loader null-loader raw-loader style-loader to-string-loader

(css-loader has to be all lowercase. Mix or upper will end in error.)

Install Webpack plugins
npm install --save-dev html-webpack-plugin webpack-merge extract-text-webpack-plugin

Create vendor.ts
nano vendor.ts

Add to vendor.ts
import '@angular/platform-browser';
import '@angular/platform-browser-dynamic';
import '@angular/core';
import '@angular/common';
import '@angular/http';
import '@angular/router';
import '@angular/forms';
import 'rxjs';

Create polyfills.ts
nano polyfills.ts

Add to polyfills.ts
import 'core-js/es6';
import 'core-js/es7/reflect';
require('zone.js/dist/zone');

if (process.env.ENV === 'production') {
  // production
} else {
  // development
  Error.stackTraceLimit = Infinity;
  require('zone.js/dist/long-stack-trace-zone');
}

Create webpack.config.js
nano webpack.config.js

Add to webpack.config.js
module.exports = require('./config/webpack.dev.js');

All files have been created in the root of the project directory we initally created. That line of code above shows a subdirectory ./config.

Create a new directory and move into it
mkdir config && cd config

Create webpack.common.js
nano webpack.common.js

Add to webpack.common.js
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const rootDir = path.resolve(__dirname, '..');

module.exports = {
  entry: {
    polyfills: './src/polyfills.ts',
    vendor: './src/vendor.ts',
    app: './src/main.ts'
  },
  resolve: {
    extensions: ['', '.js', '.ts']
  },
  module: {
    loaders: [{
      test: /\.ts$/,
      loaders: ['awesome-typescript-loader', 'angular2-template-loader']
    }, {
      test: /\.html$/,
      loader: 'html'
    }, {
      test: /\.(png|jpe?g|gif|svg|woff|woff2|ttf|eot|ico)$/,
      loader: 'file?name=assets/[name].[hash].[ext]'
    }, {
      test: /\.css$/,
      loaders: ['to-string-loader', 'css-loader']
    }]
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: ['app', 'vendor', 'polyfills']
    }),
    new HtmlWebpackPlugin({
      template: 'src/index.html'
    })
  ]
};

Create webpack.dev.js
nano webpack.dev.js

Add to webpack.dev.js
const webpackMerge = require('webpack-merge');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const commonConfig = require('./webpack.common.js');
const path = require('path');
const rootDir = path.resolve(__dirname, '..');

module.exports = webpackMerge(commonConfig, {
  devtool: 'cheap-module-eval-source-map',
  output: {
    path: path.resolve(rootDir, 'dist'),
    publicPath: 'http://localhost:8080/',
    filename: '[name].js',
    chunkFilename: '[id].chunk.js'
  },
  plugins: [
    new ExtractTextPlugin('[name].css')
  ],
  devServer: {
    historyApiFallback: true,
    stats: 'minimal'
  }
});


(So far no so good. This all doesn't acually work yet. It throws errors at the webpack dev code about missing packages. I will conclude this later after some research. I learned lots of far and understand the code the CLI produces better, and that's the point.)