webpack 2 - is there a way to do global public url replacement - webpack-2

There are few assets generated via webpack. The assets themself are pretty regular, application.js, application.css, images and so on. The point is that at runtime that assets should be hosted inside a specific server-side assembly and because of this, all the urls should be changed in this manner:
dist/application.js ==> ?path=content.application.js
dist/application.css ==> ?path=content.application.css
...and so on for every style/script/image in the output bundle.
I tried the publicPath option of output section, but it looks like this functionality is not so powerful. So if I do this:
output: {
// ...
publicPath: "?path=content."
},
When the result for root html is like this:
<script type="text/javascript" src="?path=content./application.js">/script>
<link href="?path=content./application.css" rel="stylesheet"></head>
Which is not correct as it has additional / that I cannot get rid of.
It would be great if publicPath was a function that returns dynamic path for every resource:
output: {
// ...
publicPath: function(originalFile){
return /* generate publicPath dynamically */
}
},
...but it's not the case with webpack2. So is there any method to globally replace public urls for all the resources? Or maybe some loader that does this.

Related

NestJs Swagger how to add custom favicon

I am trying to add a custom favicon to my NestJs documentation. However, I am a bit lost on how the path file gets resolved and not sure how to achieve this.
I am using nestjs/swagger module version 3.1.0 and trying to pass the path file like so when initializing the Swagger Module.
My main.ts file
SwaggerModule.setup('/v1/docs', app, document, {
customCss: CUSTOM_STYLE,
customSiteTitle: 'My API Documentation',
customfavIcon: './public/favicon.jpg'
});
Searched on the github issues and didn't find anything useful. And as you can see from the code I was able to modify the CSS styles, but I cannot figure out how to make the favicon custom.
Appreciate any help
I have added the custom favicon to my swagger docs using following:
The first thing you make sure is, in your main.ts, the app is initialized with the following:
const app: NestExpressApplication = await NestFactory.create(...)
To serve static content you must initialize your app with NestExpressApplication.
The next thing is to allow the Nest application to look for public content using the following in your main.ts after initialization:
app.useStaticAssets(join(__dirname, '..', 'public'));
Also, create a public directory in your root of the application and paste your favicon.jpg file in it.
Now its time to initialize the Swagger in main.ts
SwaggerModule.setup('/v1/docs', app, document, {
customCss: CUSTOM_STYLE,
customSiteTitle: 'My API Documentation',
customfavIcon: '../favicon.jpg'
});
You must give a relative path to the root of the application like ../favicon.jpg in case our main.ts is in src folder in root of the application.
Alternative solution, just host your favicon and reference it with external url
SwaggerModule.setup('api', app, getSwaggerDocument(app), {
...
customfavIcon:
'https://[your-bucket-url].com/.../anything.png',
});
To iterate on pravindot17's answer, now there's the #nestjs/serve-static package for hosting static files. Which avoid us from type-casting the Nest.js client and relying on our implicit assumption that we're running an Express-backed Nest.js server.
After installing the package, you hook it into your src/app.module.ts. This configuration expects that the root of your project has a /public/ folder where you store your static assets.
import { Module } from '#nestjs/common';
import { ServeStaticModule } from '#nestjs/serve-static';
import { join } from 'path';
#Module({
imports: [
// Host static files in ../public under the /static path.
ServeStaticModule.forRoot({
/**
* Config options are documented:
* https://github.com/nestjs/serve-static/blob/master/lib/interfaces/serve-static-options.interface.ts
*/
rootPath: join(__dirname, '..', '..', 'public'),
serveRoot: '/static',
}),
// ...
})
export class AppModule {}
Now my own preference is using an absolute path rather than relative, as it makes it independent from the path we picked to host our API documentation under.
SwaggerModule.setup('/v1/docs', app, document, {
customfavIcon: '/static/favicon.jpg'
});
One last note is that this configuration hosts static files from /static/*, this is done to prevent that API calls to non-existing endpoints show an error message to the end-user that the static file cannot be found.
Otherwise, all 404's on non-existing endpoints will look something like:
{"statusCode":404,"message":"ENOENT: no such file or directory, stat '/Users/me/my-project/public/index.html'"}

Porting static html/javascript site to iPad using trigger.io

Im currently in the process of porting a completely static site using trigger io to convert it to an app. The site comprises of lots of folders in folders with index.html files in them to make the urls nice. The site uses absolute urls to include stylesheets, javascripts, on a tags, and images in every page.
I would like to set a root directory for trigger.io, but I cannot find any way of doing this. Is this even possible?
Cheers,
Rich
Edit:
Example:
<script src="/json.js" type="text/javascript"></script>
<img alt="Bar_hat" class="bar_hat" src="/assets/bar_hat-09efbabebef04dd368425a6b71badfa7.jpg" />
The script tag is in all of the files.
The img tag is used in 90% of the files. These are obviously not being found from within the app.
Copy your "assests" directory to the "src" directory and use without a "slash" before assets -
<img alt="Bar_hat" class="bar_hat" src="assets/bar_hat-09efbabebef04dd368425a6b71badfa7.jpg" />
Also, if you want to access via javascript you must use this pattern:
forge.file.getUrl("assets/bar_hat-09efbabebef04dd368425a6b71badfa7.jpg",
function(file) {
// If using zepto or jquery
$("#whateverImage").attr("src", file);
},
function(err) {
// error
}
);
Edit: getUrl vs getLocal

jasmine not loading my custom js file

I am unable to get jasmine to load my custom javascript file, even though it works perfectly in the browser. I've reduced the javascript to the minimum to avoid any possibility of errors and I still get a failing test on the simplest thing.
Custom ARB.js file:
$(document).ready(function() {
alert('typeof ARB: ' + typeof ARB);
});
ARB = {};
ARB.VERSION = "V1.01.00 2012-08-24";
jasmine configuration file snippet (I'm on Rails 3.0.9):
src_files:
- "public/javascripts/**/*.js"
- "public/javascripts/ARB.js"
This test:
it('should define the custom javascript functions', function() {
expect(typeof ARB).toEqual('object');
});
fails with:
Expected 'undefined' to equal 'object'.
jQuery gets loaded and so does my application.js file. When running jasmine, I get no alert message, but I do when I run my app.
What am I missing?
UPDATE: If I remove the $(document).ready function, jasmine passes all the tests - what's that all about?
shioyama gave me the pointer that I needed to figure this out: my custom ARB.js file was getting loaded before the jquery files so it didn't have access to the $(document).ready function. What I had to do was explicitly spell out the order in which my javascript files were to be loaded. Here's what I put in my jasmine config file at /spec/javascripts/support/jasmine.yml:
src_files:
- "public/javascripts/**/jquery.js"
- "public/javascripts/**/jq*.js"
- "public/javascripts/**/application.js"
- "app/assets/javascripts/**/*.js"
- "public/javascripts/ARB.js"
I first force the main jquery.js file to load, then all the other jquery files, then application.js, then any other javascript files that are located in the assets directory, and finally my custom javascript file.
This works for me because I'm still on Rails 3.0.9 and starting the migration to 3.1+ and the asset pipeline.

Images in Grails stylesheets dont work

I'm using Grails 2.0 and specified my css stylesheets and javascript files in the application resources file so that I can use syntax like <r:require modules="common"/>
In my resource file I have specified a css file which in turn uses in image background...
jrac {
dependsOn 'jquery-dev'
resource url: '/js/misc/jrac.js'
resource url: '/css/misc/jrac.css', bundle:'bundle_style'
}
jrac.css
...
.jrac_loading {
background-image: url('../../images/misc/loading.gif');
}
The issue is that when I run this in the browser, the parsed file changes the url to:
background-image: url('resource:/images/misc/loading.gif');
So the image doesn't work, does anyone have any ideas why?
Turns out the issue was with the lesscss plugin. If you use this plugin you must set your less output to a separate bundle, otherwise url rewriting doesn't seem to play well.

Conditional javascript require in the asset pipeline

I'm struggling with the asset pipeline. I'm loading dojo from Google CDN putting this in my template:
= javascript_include_tag 'http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js', :'data-dojo-config' => %Q(dojoBlankHtmlUrl:'/blank.html', baseUrl: 'assets/', modulePaths: {custom: 'javascripts/modules'})
I just want a fallback to a local version if running locally or if the CDN is down. I thought of doing this:
script typeof(dojo) === "undefined" && document.write(unescape('%3Cscript src="js/libs/dojo-1.6.1.min.js"%3E%3C/script%3E'));
But I don't like it as it works out of the asset pipeline. I want to keep dojo in vendors/assets/javascripts/dojo. How can I get the fallback to be served by the asset pipeline.
Is there a way do declare conditional require in the asset pipeline. What I want is to run some javascript tests, and depending on the result serve a file.
Thanks
I suggest you use yepnope, a lightweight library for loading libraries like this in parallel (for speed) and it gives you the option to run some other code to test if the library is loaded. For example:
yepnope([{
load: 'http://ajax.googleapis.com/ajax/libs/dojo/1.6.1/dojo/dojo.xd.js',
complete: function () {
if (!window.jQuery) {
yepnope('asset_path('you_local_copy_of_dojo') ');
}
}
}])
(Note: You will need erb tags around the asset_path helper)
The local dojo file would be in the assets/javascript folder, but not included in the application manifest. You need to add the dojo file to the precompile array:
config.assets.precompile += 'your_local_file.js'
And this will make it available to the asset_path helper.
Thanks Richard!
I don't want to have yepnope to load one library. It would be overkill imo. Here is the solution I came up with, based on your help (written in slim):
1/ In vendors/assets/javascripts/, I have my dojo.js.
2/ In config/application.rb:
# Precompile these assets files
config.assets.precompile += ['dojo.js']
3/ In the template:
= javascript_include_tag "http://ajax.googleapis.com/ajax/libs/dojo/#{Settings.dojoVersion}/dojo/dojo.xd.js", :'data-dojo-config' => %Q(dojoBlankHtmlUrl:'/blank.html', baseUrl: 'assets/', modulePaths: {custom: 'javascripts/modules'})
script = "typeof(dojo) === \"undefined\" && document.write(unescape('%3Cscript src=\"#{asset_path('dojo')}\"%3E%3C/script%3E'));".html_safe
I also posted on the Rails Google Group to request the addition of two options to the javascript_include_tag, :test and :local that would take care of all the work. We'll see.

Resources