how to deploy your dart app (using Web ui) without using Pub Deploy - dart

What is the best strategy to deploy a Dart Web-ui app manually ?
pub deploy doesn't work for me and I have raised bug report. So am thinking what is the best way to manually deploy.
This is how I started:
1) From project root I compile the webui components (dwc.dart)
2) change directory to web/out then run dart2js
3) copy all .js files into that scripts/js public folder on server
4) copy appname.html to server changing css and script paths to option 3
5) Make sure dart.js is also in the same directory as item 3
this is as far as I got. So what else do I need to do ?
A few questions:
1) Do I manually change the file paths in the generated .js files to point to public folders on server for the files they are referencing and make sure those files are on server also ?
2) Do I need to copy all packages to server also ?
3) Any preferred file structure on server?
Any tips on this really appreciated.
Thanks.

I wrote a Grunt script for it (since I had no time to look up how to properly write code for Grunt, I did not share the code since it's a mess) but I basically do this:
compiling a list of files with dwc to a given out dir
compile it to javascript
clean up all non-deployable files
change some paths inside the HTML to match the server paths (for some reasons, this gets changed by the compilation process)
remove all packages except the ones I really need (JS interopt and browser)
Since I'm only using the JS version, I remove all dart packages. Since the paths inside the HTML files are up to you, you can already use a structure that suits you/your server.

I can provide you with a Grunt script to understand the order of tasks. Practically the order I use is this one:
Create the build directory. I usually use /build/web. I usually create these files (index.html, main.dart, /css and so on into the /web dir). I create the rest of components into /lib directory.
Compile the .dart file that contains the main() function ("main.dart" in my case for simpler projects) file to Javascript and put it into /build/web directory
Copy the other needed files and folders to the /build/web directory. Also, during this process you'll be copying the packages that your project needs. You'll see in the example provided below.
Remove all empty folders from the project
You can create a Grunt task to open the /index.html file in the browser once the building process has ended (I will not provide this example)
The structure of the dart test project:
testApp
- gruntfile.js
- package.js
/lib
/packages
/angular
/web
- index.html
- main.dart
/css
/img
So, the Grunt example script to cover steps from 1 - 4 looks like this (copy it to gruntfile.js):
module.exports = function (grunt) {
grunt.initConfig({
// 1.
// create build web directory
mkdir: {
build: {
options: {
create: ['build/web']
}
}
},
// 2.
// compile dart files
dart2js: {
options: {
// use this to fix a problem into dart2js node module. The module calls dart2js not dart2js.bat.
// this is needed for Windows. So use the path to your dart2js.bat file
"dart2js_bin": "C:/dart/dart-sdk/bin/dart2js.bat"
},
compile: {
files: {'build/web/main.dart.js': 'web/main.dart'}
}
},
// 3.
// copy all needed files, including all needed packages
// except the .dart files.
copy: {
build: {
files: [
{
expand: true,
src: [
'web/!(*.dart)',
'web/css/*.css',
'web/res/*.svg',
'web/packages/angular/**/!(*.dart)',
'web/packages/browser/**/!(*.dart)'
],
dest: 'build'
}
]
}
},
// 4.
// remove empty directories copied using the previous task
cleanempty: {
build: {
options: {
files: false
},
src: ['build/web/packages/**/*']
}
},
});
require('matchdep').filterDev('grunt-*').forEach(grunt.loadNpmTasks);
grunt.registerTask('default', [
'mkdir:build',
'dart2js',
'copy:build',
'cleanempty:build'
]);
};
So this is the Grunt script example.
Create a /gruntfile.js file into your project's root directory and copy/paste the script to it.
Create a /package.json file into your project's root directory and copy/paste the following script:
{
"name": "testApp",
"version": "0.0.1",
"description": "SomeDescriptionForTheTestApp",
"main": "",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "YourName",
"peerDependencies": {
"grunt-cli": "^0.1.13"
},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-cleanempty": "^1.0.3",
"grunt-contrib-copy": "^0.7.0",
"grunt-dart2js": "0.0.5",
"grunt-mkdir": "^0.1.2",
"matchdep": "^0.3.0"
}
}
Open Command Prompt in Windows, Terminal in Linux, navigate to your project's root directory and use this command:
npm install
Wait untill all Grunt modules needed will be downloaded to your local project. Once this is finished, issue this command in Command Prompt or Terminal:
node -e "require('grunt').cli()"
You can use this to initiate Grunt default task without having Grunt installed globally on your system.
Now, to know the exact build structure for your project (including the packages that the project needs), make a build using Pub Build. Then you will be able to instruct Grunt to create the same dir structure.
You can add other tasks (like minification) if you want.
Hope this will help you all to understand the process and get you started with a test app first. Add your comments to make this even better and simplify it even more.

Related

How can I easily reference separate js / css files for debugging when using gulp or grunt?

I'm developing a legacy ASP.NET MVC 5 project which still uses ASP.NET Bundling and Minification. I'm interested in switching to Gulp or Grunt, because I need to save source maps for my js files.
It seems easy to generate a minified script bundle with Gulp or Grunt, but what I do not understand yet is the recommended setup for loading single js files when debugging and minified bundles in production. I guess it would be quite easy to generate a razor view for including the scripts as part of my Grunt / Gulp compilation process, but it feels like re-inventing the wheel.
For instance, in ASP.NET MVC i can write something like this:
#Scripts.Render("~/bundles/MyJSBundle")
and it will automatically load separate js files in development and a single script bundle in production. What is the easiest way achieve this with Gulp or Grunt?
Short answer:
Typically when using Grunt you generate two builds - one for "dev" (development) and another for "dist" (distribution/production). Whereby for the scenario you've described;
Both the "dev" and "dist" builds generate a single concatenated/minified file version (e.g. bundle.min.js) derived from multiple source .js files.
However, only the "dev" build generates an additional Source Map file(s), that holds information about your original .js files, for the purpose of debugging during the development lifecycle.
Grunt plugins, such as grunt-processhtml, provide a way to update any links to .js assets in the .html file. For example, let's say your source .html contains these two links;
<script src="js/a.js"/>
<script src="js/b.js"/>
They can be substituted during the "dist" and/or "dev" build step to the following single <script> element:
<script src="dir/bundle.min.js"/>
Example demo:
The following somewhat contrived example demonstrates how you may approach your requirement using Grunt.
Let's say our initial project directory is structured as follows:
project
├── Gruntfile.js
├── node_modules
│   └── ...
├── package.json
└── src
├── index.html
└── js
├── a.js
└── b.js
Note, in the src directory we have a single index.html file, and two .js files in the js directory.
In the contents of index.html shown below it contains two <script> elements, each one referencing a .js file.
project/src/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>demo</title>
</head>
<body>
<!--build:js js/bundle.min.js-->
<script src="js/a.js"></script>
<script src="js/b.js"></script>
<!--/build-->
</body>
</html>
Note, the custom HTML comments encasing both <script> elements. These custom HTML comments are utilized by grunt-processhtml. The part that reads; js/bundle.min.js in the comment essentially defines the new pathname to be used.
Let's consider the following Gruntfile.js configuration:
Gruntfile.js
module.exports = function (grunt) {
grunt.loadNpmTasks('grunt-contrib-concat');
grunt.loadNpmTasks('grunt-contrib-uglify');
grunt.loadNpmTasks('grunt-processhtml');
grunt.initConfig({
// 1. Concatenate .js files.
concat: {
dist: {
src: [
'src/js/a.js',
'src/js/b.js'
],
dest: './dist/js/bundle.min.js'
},
dev: {
options: {
sourceMap: true
},
src: [
'src/js/a.js',
'src/js/b.js'
],
dest: './dev/js/bundle.min.js'
}
},
// 2. Minify .js files.
uglify: {
dist: {
files: {
'./dist/js/bundle.min.js': './dist/js/bundle.min.js' // dest : src
}
},
dev: {
options: {
mangle: false,
sourceMap: true,
sourceMapIn: './dev/js/bundle.min.js.map'
},
files: {
'./dev/js/bundle.min.js': './dev/js/bundle.min.js' // dest : src
}
}
},
// 2. Process .html file.
processhtml: {
dist: {
files: {
'./dist/index.html': './src/index.html' // dest : src
}
},
dev: {
files: {
'./dev/index.html': './src/index.html' // dest : src
}
}
}
});
grunt.registerTask('default', ['dist', 'dev']);
grunt.registerTask('dist', [
'concat:dist',
'uglify:dist',
'processhtml:dist'
]);
grunt.registerTask('dev', [
'concat:dev',
'uglify:dev',
'processhtml:dev'
]);
};
Explanation of Gruntfile.js:
In addition to the previously mentioned grunt-processhtml plugin the following two are also utilized in this example:
grunt-contrib-concat - for concatenating the two .js files.
grunt-contrib-uglify - for minifying the .js file.
Note: There are other plugins available for these types of task. I have chosen these additional two plugins for the purpose of this demonstration.
Each of the three Tasks (concat, uglify, and processhtml) contain two separate Targets named dist and dev. The main differences in each Target are:
Different dest (destination) paths for the resultant generated .jsfile(s).
For the concat:dev and uglify:dev Targets its options object defines the configuration for the resultant Source Map file.
At the end of Gruntfile.js three different grunt.registerTask() have been defined. Each one defines a taskList that essentially defines which Task and Target to run in the order specified.
For example consider the following registered task named dist:
grunt.registerTask('dist', [
'concat:dist',
'uglify:dist',
'processhtml:dist'
]);
When running grunt dist via the command line Grunt essentially invokes this Task, which subsequently performs the following in this order:
Firstly, runs the dist Target defined in the concat Task.
Then runs the dist Target defined in the uglify Task.
Finally, runs the dist Target defined in the processhtml Task.
Running Gruntfile.js (above) and its output
Running the following command via the command line:
grunt dev
outputs the following additional assets to the project directory:
project
├── ...
├── dev
│   ├── index.html
│   └── js
│   ├── bundle.min.js
│   └── bundle.min.js.map
└── ...
As you can see it has:
Created a new dev folder in the root of the project directory.
The two <script> elements originally defined in project/src/index.html have been substituted in the newly generated project/dev/index.html with a single <script> tag as follows:
<script src="js/bundle.min.js"></script>
Both files; project/src/js/a.js and project/src/js/b.js, have been concatenated and minified in the resultant project/dev/js/bundle.min.js.
The following source map file has been generated; project/dev/js/bundle.min.js.map. This file essentially maps back to the original project/src/js/a.js and project/src/js/b.js files.
Running the following command via the command line:
grunt dist
outputs the following additional assets to the project directory:
project
├── ...
├── dist
│ ├── index.html
│ └── js
│ └── bundle.min.js
└── ...
As you can see this time it has;
Created a dist folder in the root of the project directory.
Again, the two <script> elements originally defined in project/src/index.html have been substituted in the newly generated project/dist/index.html with a single <script> tag (as per the aforementioned dev Task).
Again, both files; project/src/js/a.js and project/src/js/b.js, have been concatenated and minified in the resultant project/dist/js/bundle.min.js.
However, the main notable difference is that NO source map file has been created.
Running the following command via the command line:
grunt
will produce both the outputs defined in the previous steps 1 and 2.

Electron app with Nex.js (loading html files not working)

I'm building an electron app using Next.js and electron-next package so Electron can handle the "ouput" folder from Next.js.
The app works great (simple html "hello world" test for all) for development; however, when I'm packaging the app with electron-builder, the page doesn't load and the DevTools is saying that it cannot load local files. I can see the files generated by electron-builder and nowhere I can find the static html files. Is there something I'm missing? Are the static files are included in the *.asar file?
This is for Electron under Windows 10.
Below I'm showing the package.json file setup for electron-builder, as well as the call to open the initial HTML file on the app entry file (index.js)
// ---------package.json----------
"scripts": {
"start": "electron .",
"build": "next build renderer && next export renderer",
"dist": "npm run build && electron-builder"
},
"build": {
"files": [
"**/*",
"renderer"
]
},
// --------index.js----------
// I can confirm that /renderer/out/start.html file is created
const devPath = "http://localhost:8000/start"
const prodPath = path.resolve('renderer/out/start.html')
const entry = isDev ? devPath : ('file://' + prodPath)
console.log(entry)
win.loadURL(entry)
This is the error I get:
Not allowed to load local resource: file:///C:/Users//Desktop/text_exc_app/dist/win-unpacked/resources/renderer/out/start.html
I found from another post that you can also do this (using app.getAppPath()):
const prodPath = path.join(app.getAppPath() ,'renderer/out/start.html')
This solved my problem!
I'm still not sure as to what is the difference between the two ways of accessing the files is, and why one works and the other one doesn't.

Electron Build Windows Folder Structure

Given an application made in electron. The folder structure would look something like:
App
- assets
-models
- exe files
index.html
main.js
When executing the build following the recommendation of the site by entering the following command:
electron-packager . --overwrite --asar=true --platform=win32 --arch=ia32 --icon=assets/icons/win/icon.ico --prune=true --out=release-builds --version-string.CompanyName=CE --version-string.FileDescription=CE --version-string.ProductName="Electron Tutorial App"
The electron v.1.7.9 creates the build correctly, however it inside the release-builds / resources folder the app.asar file, so all the content that was inside my models folder becomes inaccessible. Inside this folder were .exe files that should be run on demand.
The system then looks for the files in the following url: parth_do_projeto / resources / app.asar / assets / models /, that is, it considers that the app.assar is a folder, but after the app.asar build is a file.
Since there were .exe files inside the original folder, the app.asar can not absorb executables.
What would be the way I keep these .exe files? If you build the build without the --asar parameter, the program works correctly, enter, all my project folder / source code is exposed.
My question is what is the best way to generate the build, keeping the code closed and making use of .exe files?
The short answer to your question is to use the unpackDir option for the asar option inside of electron-packager. Here is a sample of what this might look like:
'use strict';
... ...
var packager = require('electron-packager');
var electronPackage = require('electron/package.json');
var pkg = require('./package.json');
// pull the electron version from the package.json file
var electronVersion = electronPackage.version;
... ...
var opts = {
name: pkg.name,
platform: 'win32',
arch: 'ia32', // ia32, x64 or all
dir: './', // source location of app
out: './edist/', // destination location for app os/native binaries
ignore: config.electronignore, // don't include these directories in the electron app build
icon: config.icon,
asar: {unpackDir: config.excludeFromASAR}, // compress project/modules into an asar blob excluding some things.
overwrite: true,
prune: true,
electronVersion: electronVersion , // Tell the packager what version of electron to build with
appCopyright: pkg.copyright, // copyright info
appVersion: pkg.version, // The version of the application we are building
win32metadata: { // Windows Only config data
CompanyName: pkg.authors,
ProductName: pkg.name,
FileDescription: pkg.description,
OriginalFilename: pkg.name + '.exe'
}
};
// Build the electron app
gulp.task('build:electron', function (cb) {
console.log('Launching task to package binaries for ' + opts.name + ' v' + opts['appVersion']);
packager(opts, function (err, appPath) {
console.log(' <- packagerDone() ' + err + ' ' + appPath);
console.log(' all done!');
cb();
});
});

Creating Shortcuts for an Installed Electron Application

I have an electron application for which I use electron-packager to compile and grunt-electron-installer to generate the Windows installer package.
Upon installation I handle the squirrel events like so:
//...
switch (squirrelCommand) {
case '--squirrel-install':
case '--squirrel-updated':
createShortcuts(cleanUp);
break;
//...
and the createShortcuts function just spawns a child process to call the Update.exe (Squirrel.exe) with the --createShortcut=myapp.exe arguments
This works, however, when the shortcut it generated it is named Electron instead of myapp.
I don't see any other ways to specify the output name of the shortcut, so how would I change the generated shortcut to say myapp?
Here is the snippet of the squirrel logs:
2016-03-20 10:34:35> ApplyReleasesImpl: Creating shortcut for myapp.exe => C:\Users\zeus\Desktop\Electron.lnk
2016-03-20 10:34:35> ApplyReleasesImpl: About to save shortcut: C:\Users\zeus\Desktop\Electron.lnk (target C:\Users\zeus\AppData\Local\myapp\Update.exe, workingDir C:\Users\zeus\AppData\Local\myapp\app-0.0.3, args --processStart myapp.exe)
Upon further investigation into electron-packager I found a more detailed explanation about the resource editing here.
using the electron-packager command line I pass these arguments to update the embedded electron exe information:
electron-packager ... --version-string.CompanyName="Company Inc." --version-string.ProductName="Product" ...
The grunt-electron-installer will look for this embedded application information to generate the name for the shortcut.
If you use electron-forge, you may want to try a config that looks like this:
"electronPackagerConfig": {
"icon": "Icon",
"win32metadata":{
"ProductName": "My App",
"CompanyName": "My Company"
}
}
More info here:
https://github.com/electron-userland/electron-forge/issues/89
Try to use electron-builder if you get painful with Squirrel. You can use the command as below to make your installer for Windows:
electron-builder path/to/your-electron-packager-output --platform=win --out=path/to/your-installer-output --config=path/to/builder.json --target=win
Sample content for builder.json:
{
"win": {
"title": "My Production Name",
"icon": "path/to/your-icon.ico",
"version": "1.0.0",
"publisher": "Your Company Name"
}
}
P.s: You must install NSIS and add NSIS path into PATH environment before you run the above command.

Proper Semantic-UI / Bower / Rails 4 configuration

I'm struggling to properly install and configure Semantic-UI using bower in my Rails 4 app.
Until now, here's what I've done:
Gemfile:
gem "less-rails"
gem "therubyracer"
.bowerrc file:
{
"directory": "vendor/assets/components"
}
bower.json:
{
"name": "app",
"version": "0.0.0",
"homepage": "myapp.com",
"private": true,
"ignore": [
"**/.*",
"node_modules",
"bower_components",
"vendor/assets/components",
"test",
"tests"
],
"dependencies": {
"semantic-ui": "~1.12.2"
}
}
After bower install, semantic UI gets properly pulled into my /vendor/assets/components folder
Now, I'd like to take advantage of semantic's theming properties, without of course editing what's currently loaded by bower.
I've added the following in semantic.css.less, itself being required in application.css
#import "semantic-ui/src/semantic";
The issue now: semantic lib seems to be properly fetched in the proper folder, as I get the following error:
'site//globals/site.variables' wasn't found
Ok I understand that.
But how do I use custom configuration files with the default assets installed by bower without touching these ?
How can I properly create the required configuration files (theme.config / site.variables / site.overrides), out of my /vendor/assets/components folder, and still properly assigning the SASS variables required for the lib to compile ?
I would take a gander at less-rails-semantic-ui, this is what I ended up going for my new rails project. It properly adds all the override files in vendor/assets!
If you are using less source files without npm (which includes an installer), you will need to manually create theme.config from theme.config.example and site/ from _site/ this is to avoid upstream changes affecting your local ui.
https://github.com/Semantic-Org/Semantic-UI/tree/master/src#config-files
PS: from the owner answer, source:
https://github.com/Semantic-Org/Semantic-UI/issues/2239

Resources