prefix assets for production with static path - ember-cli

for assets such as /assets/image.png, that I call in stylesheets, javascript etc...
I need to prefix or prepend a path to server.
so that /assets/image.png becomes /static/ember/memory/dist/assets/image.png for production.
where it will be served as ie: http://domain.com/static/ember/memory/dist/assets/image.png
i need to pass and use a STATIC_PATH variable when compiled/built for production that will be prefixed, or compile it so that it does it automatically.
I have checked ember-cli docs for assets compilation:
var app = new EmberApp({
fingerprint: {
prepend: '/static/ember/memory/dist/'
}
});
however, this doesn't work as where the assets are being called the path doesn't change in production, unless it actually modified the path where it's called.
for example in styles.css if I call /assets/image.png somewhere, I need to prefix this with STATIC_PATH + /assets/image.png when in production.
the STATIC_PATH will look something like:
/static/ember/memory/dist/
I can add this manually for production in development, but then cannot test in development.
thanks for any response.

You can pass a prepend option in the ember-cli-build file, you will have to exclude the assets that don't need the path:
var app = new EmberApp({
fingerprint: {
exclude: ['excludedAssets/'],
prepend: '/static/ember/memory/dist/'
}
});
For more information check out asset compilation

Related

How to include dlls in flutter build windows

I am working on a flutter project that runs fine in development.
However I do not know how to get the build to include dll's referenced using FFI.
I can't find clear instructions on how to do it.
I tried following the steps to build an msix here, which worked but didn't seem to include the dll (it fails in the same way as the regular build)
what is the procedure to have the build process consider the dll's?
other dll's show up in the build directory from 3rd party packages so there must be a way right?
That's really hard to discover by your own, but indeed you can bind those libraries to you MSIX. In my case I just made a package for label printers using Dart FFI and DLL`s provided by manufacturer and this is how I did it.
You need to add these DLL's to your assets setting on pubspec.yaml from your package. This is my case:
[...]
flutter:
[...]
assets:
- assets/WinPort.dll
- assets/Winppla.dll
- assets/Winpplb.dll
- assets/Winpplz.dll
With this setting you will embed your DLL files in your final MSIX, but this was the easy part. Now you have make sure to load the proper load these files in code.
Based on my own tests, I still dealing with two ways to develop and test code, the first one is when I am running a project in my machine via flutter run I must set the target for current.path, when I get it done and start building for deploy I change this to resolvedExecutable.parent.path. Where is what you need to do.
Loading you DLL in development environment (flutter run):
final String _packageAssetsDirPath = normalize(join(Directory.current.path,'assets'));
On production environment (running from .exe or MSIX installed):
final String _assetsPackageDir = normalize(
join('data', 'flutter_assets', 'packages', 'YOUR_PACKAGE_NAME', 'assets'));
final String _exeDirPath = File(Platform.resolvedExecutable).parent.path;
final String _packageAssetsDirPath =
normalize(join(_exeDirPath, _assetsPackageDir));
After with this var called _packageAssetsDirPath will be easy to load your DLL's, now you invoke a DynamicLibrary constructor:
// Path for DLL file
final String _libDllSourceFullPath =
normalize(join(_packageAssetsDirPath, 'Winppla.dll'));
// Target for copy, place DLL in same place the .exe you are running
final String _libDllDestFullPath =
normalize(join(_packageAssetsDirPath, 'YOUROWN.dll'));
// Try to copy for running exe path
File(_libDllSourceFullPath).copySync(_libDllDestFullPath);
// With this copy, would be simple to load, and if it fails, try in full path
// LOAD DLL
try {
String _packageAssetsDirPath =
normalize(join(Directory.current.path, 'assets'));
String _printerLibraryPath =
normalize(join(_packageAssetsDirPath, 'Winppla.dll'));
DynamicLibrary _library = DynamicLibrary.open(_printerLibraryPath);
return _library;
} catch (e) {
try {
DynamicLibrary _library = DynamicLibrary.open('Winppla.dll');
return _library;
} catch (e) {
// Avoing errors creating a fake DLL, but you could deal with an exception
return DynamicLibrary.process();
}
}
At this point you can load a DLL and use it, you can check my package full code at https://github.com/saviobatista/argox_printer check for lib/src/ppla.dart at function _setupDll() and you will see that loading.
I built a simpler option inspired in the solution of Sávio Batista
(You must have your .dll in your assets folder)
if (kReleaseMode) {
// I'm on release mode, absolute linking
final String local_lib = join('data', 'flutter_assets', 'assets', 'libturbojpeg.dll');
String pathToLib = join(Directory(Platform.resolvedExecutable).parent.path, local_lib);
DynamicLibrary lib = DynamicLibrary.open(pathToLib);
} else {
// I'm on debug mode, local linking
var path = Directory.current.path;
DynamicLibrary lib = DynamicLibrary.open('$path/assets/libturbojpeg.dll');
}
Just replace libturbojpeg.dll for your .dll

Include node module as a file to inject

I want to include /node_modules/es6-shim/es6-shim.min.js into the client side in Sails v0.11.
I've tried including it into the pipeline as such:
var jsFilesToInject = [
// Load sails.io before everything else
'js/dependencies/sails.io.js',
/* INCLUDE NODE MODULE */
'/node_modules/es6-shim/es6-shim.min.js',
// Dependencies like jQuery, or Angular are brought in here
'js/dependencies/**/*.js',
// All of the rest of your client-side js files
// will be injected here in no particular order.
'js/**/*.js',
// Use the "exclude" operator to ignore files
// '!js/ignore/these/files/*.js'
];
Is this possible? I don't really want to use bower or a CDN, I would like to install/update the dependency via npm.
The simplest way to accomplish this would be to leave the pipeline.js file alone and just make a symlink inside of assets/js pointing to the file you want, e.g.:
ln -s ../../node_modules/es6-shim/es6-shim.min.js assets/js/es6-shim.min.js
Next time you run sails lift, Grunt will see the new Javascript file in your assets/js folder and process it with the rest.
If this is for some reason not an option, you'll need to add a new subtask to the tasks/copy.js Grunt task:
dev_es6: {
files: [{
expand: true,
src: ['./node_modules/es6-shim/es6-shim.min.js'],
dest: '.tmp/public/js'
}]
}
and then add that to the compileAssets task in tasks/register/compileAssets:
module.exports = function (grunt) {
grunt.registerTask('compileAssets', [
'clean:dev',
'jst:dev',
'less:dev',
'copy:dev',
'copy:dev_es6', // <-- adding our new subtask
'coffee:dev'
]);
};

How to redirect assets to public, make public invisible and make lessMiddleware work

Yesterday I had a public folder with generated css, and a source folder with less
root
/public
/css
/source
/less
and a less middleware like this
module.exports = function (app, dir) {
return lessMiddleware(path.join(dir, 'source', 'less'), {
dest: path.join(dir),
preprocess: {
path: function(pathname, req) {
return pathname.replace('public' + path.sep + 'css' + path.sep, '');
}
}
});
};
It works fine, except that root dir is open, and I can get access to public folder. So, I put a NGINX as proxy, and had no problems, it denies access to root folder and redirects 'assets' to 'public'.
So I had url's like http://localhost/assets/css/main.css
Today I want to get rid of nginx for debug purposes. So I give static access to assets folder like this
if (settings.debug) {
app.use('/assets', express.static(path.join(__dirname, "public")));
}
The problem is that less middleware stopped working, because this code changes path for middleware to
c:\node\myproject\source\less\assets\css\main.less
Is there a way to redirect 'assets' to 'public' using express js standard static middleware? Or a standard way to substitute '/assets' with '/public' and pass this request forth?
I can do that with app.get(... and parse request and so on. I also can change middleware 'preprocess' directive. But I want to spend as less code as possible.
P.S.
Ok, now I can make assets work
if (settings.debug) {
app.use(function(req, res, next) {
if (req.url.indexOf('/assets/') === 0) {
req.url = req.url.replace('/assets/', '/public/');
}
next();
});
}
app.use(require('./config/lessMiddlewareConfig.js')(__dirname));
app.use('/public', express.static(path.join(__dirname, 'public')));
but I want to deny access to public now.
On your server is it actually necessary to use less middleware?
I got around this, buy adding this to my deployment shell script:
curl http://localhost:3000/stylesheets/style.css > /dev/null
which forces a recompile by requesting the css file directly to the node process.

Sharing a public tree in an ember-cli addon

I am completely puzzled when I read all the information I can gather about sharing a public assets directory from an ember-cli addon.
Is there anybody having it working around here? Any ref to an example addon doing it would also be appreciated...
So... I finally found a way to share the static assets:
- I placed the files in vendor/assets directory
- Declared the files to shared (each file...) into the addon's index.js file # addon's root
app.import('vendor/assets/my_image.png');
An interesting option of app.import statement I found in my searches is destDir, which allows to customize the target publication path of the asset:
app.import('vendor/assets/a/b/c/my_image.png', { destDir: 'x/y' });
will publish my_image.png # URL /assets/x/y/my_image.png
Hoping this will help others to save time...
Assets of addons are available under a namespace. For example if there is a file in public/assets/image.png in your addon, this file is available under /my-addon/assets/image.png.
If you don't want to use a namespace, you can overwrite the treeForPublic hook in the addon definition as demonstrated in this gist:
const Funnel = require('broccoli-funnel');
const mergeTrees = require('broccoli-merge-trees');
module.exports = {
name: require('./package').name,
treeForPublic: function(tree) {
const assetsTree = new Funnel('public');
return mergeTrees([tree, assetsTree], {
overwrite: true,
});
},
};

Concatenating and minifying RequireJS with Grunt

I have a project written in CoffeeScript that uses AngularJS. My vendor dependancies are installed using Bower and my file structure is like this:
- assets
- js
- app
- model
- *.coffee
- factory
- *.coffee
...
- app.coffee
- config.coffee
- routes.cofeee
- vendor
- angular
- lodash
...
- dist
What I'm trying to do is the following:
I'm trying to work out how I can use RequireJS's r.js to optimise my app files so that I essentially get a concatenated file all ordered nice (so vendor dependancies, my config and routes, and they my app files).
Integrate this into my Grunt file.
I've tried using the r.js optimiser but maybe I've being too silly as all it seems to do is copy my app files (minus the vendor dependancies) into the dist folder; it does, however, manage to optimise the coffee generated js files.
Has anyone got any experience with this?
I figured it out: r.js works by reading your mainConfigFile and any modules you name within your configuration, the important note here is that r.js only looks at the first require/define within your named modules and goes off to seek them; so, for example, I had one named module called app:
require ['config'], (cfg) ->
require ['angular'], (A) ->
A.module cfg.ngApp, []
require ['routes'], () ->
require [
'factory/a-factory',
'service/a-service',
'controller/a-controller'
], () ->
A.bootstrap document, [cfg.ngApp]
The problem here was that r.js never got past the first require statement and thus the concatenation wasn't working. When I changed this to, say (my app.coffee):
require ['config'], (cfg) ->
require ['angular'], (A) ->
A.module cfg.ngApp, []
require ['bootstrap'], (bootstrap) ->
bootstrap()
And my bootstrap.coffee:
define [
'config',
'angular',
'routes',
'factory/a-factory',
'service/a-service',
'controller/a-controller'
], (cfg, A, routes) ->
class Bootstrap
constructor: () ->
routes()
A.bootstrap document, [cfg.ngApp]
This meant that I only needed to define angular and bootstrap in my r.js configuration as includes and then r.js would do the rest, like so:
baseUrl: 'assets/js/app',
mainConfigFile: 'assets/js/app/config.js',
name: 'app',
include: [
'../vendor/requirejs/require',
'bootstrap'
],
out: 'assets/js/dist/app.js'
And now it all works fine! ~~It's a shame that I have to tell r.js to include requirejs though, maybe I've done something silly there?~~
Blimey, I'm such a dingus!
So in my HTML I was loading my concatenated script as:
<script src="assets/js/dist/app.js"></script>
When really it should be loaded like this:
<script src="assets/js/vendor/requirejs/require.js" data-main="assets/js/dist/app"></script>
D'oh!
From r.js doc
https://github.com/jrburke/r.js/blob/master/build/example.build.js#L322
Nested dependencies can be bundled in requireJS > v1.0.3
//Finds require() dependencies inside a require() or define call. By default
//this value is false, because those resources should be considered dynamic/runtime
//calls. However, for some optimization scenarios, it is desirable to
//include them in the build.
//Introduced in 1.0.3. Previous versions incorrectly found the nested calls
//by default.
findNestedDependencies: false,