Is there a Sprockets method that returns the relative path of the asset? - sinatra

This is a Sinatra app using a Sprockets Rack endpoint. When I reference a JavaScript file from an HTML page, I'd like to use a relative path to point to its location instead of just including the script file into the HTML. Doing so would enhance debugging, at the very least.
The Sprockets Rack definition in config.ru is:
map '/assets' do
SPROCKETS = Sprockets::Environment.new
SPROCKETS.append_path File.join(SPROCKETS.root, '/public/assets/js')
SPROCKETS.append_path File.join(SPROCKETS.root, '/public/assets/css')
SPROCKETS.append_path File.join(SPROCKETS.root, '/public/assets/fonts')
SPROCKETS.append_path File.join(SPROCKETS.root, '/public/assets')
SPROCKETS.paths.each{|path| puts path;}
SPROCKETS.js_compressor = :uglify
SPROCKETS.css_compressor = :scss
run SPROCKETS
end
To reference a JavaScript file in HTML, I define it within a script tag that effectively includes the source as a string as follows: (this works)
<script><%= SPROCKETS["frontend.js.erb"].to_s %></script>
What I would like to do is reference the file as an independent source as follows:
<script type="text/javascript" src="<%= SPROCKETS["frontend.js.erb"].filename %>"></script>
That option returns the following message:
Not allowed to load local resource: file:///C:/Bitnami/rubystack-2.2.5-3/projects/myapp/public/assets/js/frontend.js.erb
Obviously, this occurs because the Sprockets "filename" method returns the full path and the page cannot access the local file system. What I need is a method that returns the server's relative path.

Alright, just another head-slap moment...
Should have been using the standard assets path defined right there in the config.ru that I entered, as follows:
<script type="text/javascript" src="assets/frontend.js.erb"></script>
Works great.

have you tried using sprockets-helpers gem? this works with latest sprockets version. That gem allows you to use helper method to generate exactly what you need. If you are using SASS you can also check sprockets-sass gem. Works great with Sprockets 2.x and 3.x.

Related

Symfony4 Deployment with Encore

The current documentation says, that I only need the files under public/build, created with ./node_modules/.bin/encore production, when I want to deploy for production. But also to add public/build to git ignore. Do I have to copy the content of public/build manually?
In Symfony3 my deploy looked like that:
git pull
bin/php bin/console cache:clear --env=prod --no-debug
bin/php bin/console assets:install --env=prod
bin/php bin/console assetic:dump --env=prod --no-debug
FYI, Using assetic was the »old« way, and starting Symfony 2.8 Assetic is not included in the standard framework anymore (but you can still add it).
Regarding public/build you misunderstood it a bit - the actual source files should be somewhere else, for example in assets/css/app.scss and assets/js/app.js. Using Webpack Encore, running ./node_modules/.bin/encore production will minify, uglify, etc (whatever you configure in webpack.config.js) these source files and then copy the generated files to public/build. So public/build will only contain the generated stuff and thus can be safely added to .gitignore (but you also need to run the encore script in production).
Your JavaScript file (i.e. in this case app.js) should include
require('../css/app.scss');
so that the app.scss is actually a dependency of app.js and you only need to tell the webpack.config.js to include the JavaScript file. The basic configuration of webpack.config.js might look like this:
// webpack.config.js
var Encore = require('#symfony/webpack-encore');
Encore
// this will put all your compiled stuff into public/build, that’s
// why you can put this into .gitignore, because you can re-build this
// from the source files.
.setOutputPath('public/build/')
// the public path used by the web server to access the previous directory
.setPublicPath('/build')
// this will create public/build/app.js, and also public/build/app.css
// since the scss file is a dependency of app.js
.addEntry('app', './assets/js/app.js')
// allow sass/scss files to be processed
.enableSassLoader()
[...]
;
// export the final configuration
module.exports = Encore.getWebpackConfig();
You can find some more explanation under https://symfony.com/doc/current/frontend/encore/simple-example.html (first example) or https://symfony.com/doc/current/frontend.html (overview)

What is module Vs location Vs package in SystemJS configuration?

I'm little confused by various terminologies used in the SystemJS configuration. It talks about module, location, package etc...
Isn't module in JS is a single file, and package is a collection of modules or files? If so, how a module can be an alias to a package?
This is from the documentation page:
The map option is similar to paths, but acts very early in the normalization process. It allows you to map a module alias to a location or package:
Yes module is a single file, in javascript it's just the file name (with assumed .js extension) in quotes after from keyword in
import ... from 'some-module';
In SystemJS config file, paths and map can be used to define what actual file or URL that some-module refers to.
packages in config file allow you to apply a set of configuration parameters (default extension, module format, custom loader etc) for all modules in or below particular location (the key in packages object).
One of the settings in packages is main, which is similar to main in package.json in node (except that it's default value is empty, not index.js): it determines which file is loaded when the package location itself appears in from in import statement.
So, I think "how a module can be an alias to a package?" question about this
The map option is similar to paths, but acts very early in the
normalization process. It allows you to map a module alias to a
location or package:
can be explained on this example:
paths: {
'npm:': 'node_modules/'
},
map: {
'some-module': 'npm:some-module'
},
packages: {
'some-module': {
main: './index.js'
}
}
when these map, packages and path settings are applied by SystemJS to
import something from 'some-module';
they will cause SystemJS to load a module from node_modules/some-module/index.js under baseURL.
and
import something from 'some-module/subcomponent';
is mapped to node_modules/some-module/subcomponent.js.
Note: this is based on my experience with SystemJS 0.19. I haven't tried 0.20 yet.

What is the physical path of Odoo webserver?

I'm building a custom odoo module that will be using several Javascript libraries.
I need to add references to those libraries (local references) but I don't know exactly where to place those libraries and how to refer to their location.
What I tried:
- I created the new module and placed the libraries inside the module directory but it didn't work.
- I also placed the libraries in the home directory of odoo.
As I understand, the problem would be solved if I could get the default directory of the webserver that odoo runs on.
If module is using js files, then you must put these files inside your module. And still if you cant reach these files from your module its your technical error and you have to fix it yourself, also note that odoo has its js libraries already
I found this page: how to add css and js files in Openerp 7 / Odoo module maybe can help you.
Below is the content.
Store files correctly:
CSS and JS files should be reside under 'static' directory in the module(the rest of subdirectory tree under 'static' is an optional convention):
static/src/css/your_file.css
static/src/js/your_file.js
Add files in manifest (v7.0) or in XML(v8.0)
Openerp v7.0 way is to add following entries in manifest (in openerp.py):
...
'css': ['static/src/css/your_file.css'],
'js': [static/src/js/your_file.js'],
...
Odoo v8.0 way is to add corresponding record in the XML:
Add XML to the manifest (openerp.py):
...
'data': [ 'your_file.xml'],
...
Then add following record in 'your_file.xml':
<data>
<template id="assets_backend" name="your_module_name assets" inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<link rel='stylesheet' href="/your_module_name/static/src/css/your_file.css"/>
<script type="text/javascript" src="/your_module_name/static/src/js/your_file.js"></script>
</xpath>
</template>
....
....
</data>

how to include a local javascript im ember-cli application

I have a local javascript in my application that i want to include in my ember-cli application.
it is called carrotsearch.foamtree.js
In order that it will be included i put it under vendor\foamtree\carrotsearch.foamtree
and in the app.js i write
import CarrotSearchFoamTree from 'foamtree/carrotsearch.foamtree'
the problem is that i get an error
===== 1 JSHint Error
Build failed. ENOENT, no such file or directory
'C:\Users\davidga\Desktop\ember\nextgen\tmp\tree_merger-tmp_dest_dir-37cYqLzL.tmp\foamtree\carrotsearch.foamtree.js'
File: foamtree/carrotsearch.foamtree.js Error: ENOENT, no such file or directory C:\Users\davidga\Desktop\ember\nextgen\tmp\tree_merger-tmp_dest_dir-37cYqLzL.tmp\foamtree\carrotsearch.foamtree.js'
at Object.fs.statSync (fs.js:689:18) at addModule
(C:\Users\davidga\Desktop\ember\nextgen\node_modules\ember-cli\no
de_modules\broccoli-es6-concatenator\index.js:83:46) at addModule
(C:\Users\davidga\Desktop\ember\nextgen\node_modules\ember-cli\no
de_modules\broccoli-es6-concatenator\index.js:126:9) at
C:\Users\davidga\Desktop\ember\nextgen\node_modules\ember-cli\node_modules\
broccoli-es6-concatenator\index.js:59:7 at tryCatch
(C:\Users\davidga\Desktop\ember\nextgen\node_modules\ember-cli\nod
e_modules\rsvp\dist\commonjs\rsvp-internal.js:163:16) at
invokeCallback
(C:\Users\davidga\Desktop\ember\nextgen\node_modules\ember-c
li\node_modules\rsvp\dist\commonjs\rsvp-internal.js:172:17) at
publish
(C:\Users\davidga\Desktop\ember\nextgen\node_modules\ember-cli\node
_modules\rsvp\dist\commonjs\rsvp-internal.js:150:13) at flush (C:\Users\davidga\Desktop\ember\nextgen\node_modules\ember-cli\node_m
odules\rsvp\dist\commonjs\rsvp\asap.js:51:9) at
process._tickCallback (node.js:419:13)
I thought that the problem is maybe bower related so i followed the following post how to include a private local file in javascript project using bower
The problem is that neither
"foamtree": "foamtree/carrotsearch.foamtree.js"
nor
"foamtree": "vendor/foamtree/carrotsearch.foamtree.js"
works.
What may i do?
Thanks,
David
I found an answer.
In brocfile.js we can add the line
app.import('vendor/foamtree/carrotsearch.foamtree.js')
I don't know if this is an optimal anser but it works
Update:
This solution is stated in the ember-cli documentation
http://iamstef.net/ember-cli/#managing-dependencies
If you don't need them to minified in your vendor.js file you can put them in the public/js and then include it as a normal script file in app/index.html. I use this method for some libraries like moment.js.
The public folder gets directly copied to your site root during the build.

Gwt static resource from subfolders not found

I have a problem with path to javascript in my GWT html.
I get: WARNING: No file found for: /smartajax/libs/historyjs/history.html4.js and more like this
File exists in my war/html1 dir.
It happens only if script like this above is called not from my Html1.html, but from other script that is in public (its not declared in html by <script type="text/javascript" ...>
- public_res
- smartajax
- libs
- historyjs
- war
- html1
- smartajax
- libs
- historyjs
<script type="text/javascript" src="html1/smartajax/load.smartajax.js"></script>
How to solve this?
You should ideally place all your third party scripts in same relative folder.
1) All in public/thirdparty
2) All in war/thirdparty
Your gwt public resource folder is compiled into your module's folder, and not war base directory. It will be compiled into war/module_name/html1/smartajax/... So, instead of using relative uris, how about absolute uris?
GWT.getHostPageBaseURL() -> Base url for html page, http://x.y/
GWT.getModuleBaseURL() -> Base url for gwt module, http://x.y/module_name/