CEF, ES6, Angular 2, WebPack 2 .Net Core десктопное приложение без серверной части

в 13:19, , рубрики: .net, .net core, angular 2, AngularJS, C#, c++, CEF, ES6, Google Chrome, javascript, TypeScript

Это продолжение статей:

CEF, ES6, Angular 2, TypeScript использование классов .Net Core. Создание кроссплатформенного GUI для .Net с помощью CEF
CEF, Angular 2 использование событий классов .Net Core

Основная идея этих статей — создание кроссплатформенных приложений на CEF с использованием Angular 2 и .Net Core. Чтобы отвязаться от сервера, используем свежий WebPack и настроим на локальное использование файлов.

Для начала создадим package.json.

Содержимое package.json

{
  "name": "helloapp",
  "version": "1.0.0",
  "scripts": {
    "start": "tsc && concurrently "tsc -w" "lite-server" ",
    "lite": "lite-server",
    "tsc": "tsc",
    "tsc:w": "tsc -w"
  },
  "dependencies": {
    "@angular/common": "~2.4.0",
    "@angular/compiler": "~2.4.0",
    "@angular/core": "~2.4.0",
    "@angular/forms": "~2.4.0",
    "@angular/http": "~2.4.0",
    "@angular/platform-browser": "~2.4.0",
    "@angular/platform-browser-dynamic": "~2.4.0",
    "@angular/router": "~3.4.0",
    "@angular/upgrade": "~2.4.0",
    "angular-in-memory-web-api": "~0.2.4",
    "babel-preset-es2015": "^6.22.0",
    "babel-preset-es2016": "^6.22.0",
    "babel-preset-react": "^6.23.0",
    "bootstrap": "^3.3.7",
    "core-js": "^2.4.1",
    "css-loader": "^0.26.1",
    "jquery": "^3.1.1",
    "postcss-loader": "^1.3.0",
    "raw-loader": "^0.5.1",
    "reflect-metadata": "^0.1.9",
    "rxjs": "^5.1.1",
    "sass-loader": "^6.0.0",
    "style-loader": "^0.13.1",
    "systemjs": "^0.20.7",
    "to-string-loader": "^1.1.5",
    "ts-loader": "^2.0.0",
    "typescript": "^2.1.6",
    "webpack": "^2.2.0",
    "webpack-fail-plugin": "^1.0.5",
    "webpack-notifier": "^1.5.0",
    "zone.js": "^0.7.7"
  },
  "devDependencies": {
    "@types/core-js": "^0.9.35",
    "@types/node": "^6.0.46",
    "babel-core": "6.23.1",
    "babel-eslint": "7.1.1",
    "babel-loader": "6.3.0",
    "babel-plugin-__coverage__": "^11.0.0",
    "babel-polyfill": "^6.0.0",
    "babel-preset-angular2": "^0.0.2",
    "babel-preset-es2015": "^6.22.0",
    "bootstrap-loader": "^2.0.0-beta.20",
    "bootstrap-sass": "^3.3.7",
    "chunk-manifest-webpack-plugin": "^1.0.0",
    "concurrently": "^3.1.0",
    "css-loader": "^0.26.1",
    "css-to-string-loader": "^0.1.2",
    "extract-text-webpack-plugin": "^2.0.0-rc.3",
    "file-loader": "^0.10.0",
    "html-webpack-plugin": "^2.28.0",
    "jquery": "^3.1.1",
    "lite-server": "^2.2.2",
    "node-sass": "^4.5.0",
    "resolve-url-loader": "^1.6.1",
    "sass-loader": "^6.0.0",
    "style-loader": "^0.13.1",
    "typescript": "^2.1.5",
    "url-loader": "^0.5.7"
  }
} 

Здесь собраны загрузчики, ссылки на необходимые файлы итд, которые были подобраны долгими исканиями.

Так же необходим tsconfig.json для компиляции TypeScript-файлов.

Содержимое tsconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "moduleResolution": "node",
    "sourceMap": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "removeComments": false,
    "noImplicitAny": true,
    "suppressImplicitAnyIndexErrors": true,
    "lib": [ "es6", "dom" ],
    "types": [ "node" ],
    "typeRoots": [
      "node_modules/@types"
    ]
  },
  "exclude": [
    "node_modules",
    "wwwroot",
    "**/*.spec.ts"
  ],

  "compileOnSave": true
}

Теперь мы можем создать на основании package.json директорию node_modules с помощью команды npm install из директории приложения.

Прежде чем вызывать WebPack, нужно создать несколько файлов polyfills.ts.

Содержимое polyfills.ts

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

if (process.env.ENV === 'production') {
  // Production
} else {
  // Development and test
  Error['stackTraceLimit'] = Infinity;
  require('zone.js/dist/long-stack-trace-zone');
}

Добавить в main.ts ссылки на Bootstap и JQuery:


import 'jquery';
import 'bootstrap-loader';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap/dist/css/bootstrap-theme.css';

Теперь нам доступны стили, glyphicons и тд. Теперь перейдем к самому главному, а именно webpack.config.js, на основании которого и будут собираться нужные нам файлы.

var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require("extract-text-webpack-plugin");

var helpers = require('./helpers');
var babelOptions = {
  "presets": [
    "react",
    [
      "es2015",
      {
        "modules": false
      }
    ],
    "es2016"
  ]
};

module.exports = {
  cache: true,
  entry: {
    polyfills: './app/polyfills.ts',
    main: './app/main.ts',
    vendor: [
      'babel-polyfill'
    ]
  },
  output: {
    path: './wwwroot',
    filename: './scripts/[name].js',
    chunkFilename: './scripts/[chunkhash].js',
    publicPath: './'
  },
  module: {
    rules: [{
      test: /.ts(x?)$/,
      exclude: /node_modules/,
      include: /app/,
      use: [
        {
          loader: 'babel-loader',
          options: babelOptions
         
        },
        {
          loader: 'ts-loader'
        }
      ]
    }, {
      test: /.js$/,
      exclude: /node_modules/,
      include: /app/,
      use: [
        {
          loader: 'babel-loader',
          options: babelOptions
        }
      ]
    },
      { test: /.html$/, loader: 'raw-loader', exclude: [helpers.root('app/index.html')] },
      { test: /.(png|jpg|jpeg|gif|svg)$/, loader: 'url-loader', query: { limit: 25000 } },
      { test: /.css$/, loader: 'css-to-string-loader!css-loader' },
      { test: /.scss$/, loaders: ['style', 'css', 'postcss', 'sass'] },
      { test: /.(woff2?|ttf|eot|svg)$/, loader: 'url-loader?limit=10000' },
      { test: /bootstrap/dist/js/umd//, loader: 'imports?jQuery=jquery' }


    ]
  },
   resolve: {
       extensions: ['.ts', '.tsx', '.js','.css']
   },
   plugins: [
  // Workaround for angular/angular#11580
  
  new webpack.optimize.CommonsChunkPlugin({
      name: ['app', 'vendor', 'polyfills']
  }),

  new HtmlWebpackPlugin({
      template: 'app/index.html'

  }),
    new ExtractTextPlugin(
        {
            filename: 'styles.css',
            disable: false,
            allChunks: true
        }
),
new webpack.ProvidePlugin({
    jQuery: 'jquery',
    $: 'jquery',
    jquery: 'jquery'
})
   ]
};

Здесь собрано всё, чтобы использовать es6 и всё собиралось в несколько файлов в директории
'./wwwroot'. Теперь можно запустить webpack --config webpack.config.js, который и создаст нужные нам файлы.

Но нам придется подправить выходной index.html. Почему-то для:

<script type="text/javascript" src="././scripts/polyfills.js"></script>
<script type="text/javascript" src="././scripts/vendor.js">
</script><script type="text/javascript" src="././scripts/main.js"></script>

Добавляются лишние ./ — убрав ./, мы можем запустить index.html в любом браузере. Но нас интересует наш cefsimple.exe:

Укажем в адресе файла путь к index.html, например, d:CEFCefProgectsTestTypeScriptTestTypeScriptwwwrootindex.html

И Вуаля, мы работаем автономно, без Web-сервера. Если нужно подключиться к серверу, у нас есть все на .Net. Например, .Net Core, WCF и ODATA-клиенты.

Ссылки на исходники и программы и инструкцию использования можно найти в предыдущих статьях в самом низу.

Автор: Serginio1

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js