Это продолжение статей:
→ CEF, ES6, Angular 2, TypeScript использование классов .Net Core. Создание кроссплатформенного GUI для .Net с помощью CEF
→ CEF, Angular 2 использование событий классов .Net Core
Основная идея этих статей — создание кроссплатформенных приложений на CEF с использованием Angular 2 и .Net Core. Чтобы отвязаться от сервера, используем свежий WebPack и настроим на локальное использование файлов.
Для начала создадим 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-файлов.
{
"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.
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