Service workers should not reference the root level, right? - service-worker

These two examples have files at the root level:
Mozilla.org and
medium.com
But I think the files to cache should not begin with the root. Maybe I've got it wrong and that service workers is redefining what the root is.
Or maybe they're just starting with the root because the root is the only thing in their example. If the folder structure is this:
service-workers
|_ index.html
|_ styles.css
|_ main.js
|_ sw.js
|_ assets
|_ logo.png
then why is the JavaScript this?
var filesToCache = [
'/', // index.html
'/main.js',
'/styles.css',
'/assets/logo.png'
];
Shouldn't it be this instead?
var filesToCache = [
'./index.html',
'./main.js',
'./styles.css',
'./assets/logo.png',
'./assets/favicon.ico'
];

Related

Can I create a `gramex` `microservice` that automatically takes the subdirectories and renders the `markdown` in them?

I am trying to create a Gramex application. The intention is to:
See the root folder readme.md page when I access localhost:9988 (local gramex generic port)
See the readme.md in subdir1 when I access localhost:9988/subdir1/
See the readme.md in subdir2 when I access localhost:9988/subdir2/
For that I have a gramex.yaml file, that reads
url:
app:
pattern: /$YAMLURL/
handler: FileHandler
kwargs:
index: false
path:
"": $YAMLPATH/{dir}/readme.md
transform:
"*.md":
encoding: utf-8
function: markdown.markdown(content)
headers:
Content-Type: text/html; charset=UTF-8
default:
dir: ""
file: readme
ext: md
Here localhost:9988 renders the root folder readme.md.
However, browsing localhost:9988:subdir1 renders the directory index, implying that subdirs are not working.
Wondering if this is possible or not.

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.

How to build with Electron-Builder when index.html has relative path

I want to build a project written in electron.js with Electron-builder when index.html file in the parent directory, a simple app with structure like below:
project
├── css
│ ├── style.css
│ └── img.png
├── electron
│ ├── main.js
│ └── package.json
│── index.html
│── index.js
└── icon.png
use win.loadFile('./../index.html'); in the main.js file, everythings works fine when use electron . command in the electron folder, but after run electron-builder, when run the app with the executable file nothing works and the index.html file doesn't appear.
I was trying to use files config in the package.json file but no success:
"build": {
"appId": "x.y.z",
"productName": "projectName",
"files": ["**/*", "build/icon.*", "../**/*"]
},
I don't know what to do ?!
I've found this issue https://github.com/electron-userland/electron-builder/issues/2693 but can't undestand it and don't know what should I do?
I can't answer in the general case, but here's the solution when using vue-electron-builder and TypeScript. This will let you organize your files in any arbitrary hierarchy.
Create a file vue.config.js in your project root (this more or less corresponds to the overrides you'd need for an electron project with webpack):
module.exports = {
pluginOptions: {
electronBuilder: {
// my 'main' process is in src/main.ts:
mainProcessFile: 'src/main/main.ts',
// my 'main.ts' should get recompiled if any of these change:
mainProcessWatch: [
'src/main/extra_file_1.ts',
'src/main/extra_file_2.ts',
]
}
},
pages: {
// I only have one renderer process (otherwise I'd need another entry in 'pages')
"renderer": {
// 'main' for the renderer process
entry: "src/renderer/main.ts",
// this is the part you care about: you can put the template anywhere
template: "src/viewer/index.html",
// this makes sure your renderer page has all the ts-to-js chunks it needs
chunks: ["chunk-vendors", "chunk-common", "renderer"]
}
}
};
Note that if you want your index.html to <link> to a static css file, you should put the static file in the public folder of your project root. Then you can link to it like this:
<link rel="stylesheet" href="<%= BASE_URL %>my_css_file.css">

How to add multiple source_path in Rails Webpacker

We are using Webpacker for loading JavaScripts and CSS files into the webpage.
Currently, in webpacker.yml we have set the source_path to app/javascript. Which is working fine to load the JavaScript files form this directory.
But in our application, we have an engines directory, and all the JavaScript files are located inside different engines in engines directory, to load these JavaScript files we created a link in app/javascript/packs for each pack in engines directory.
Is there a better way to do this, without providing links OR by providing multiple source_path in the webpacker.yml file.
For reference:
This is the folder structure currently we have:
-root
|
|-app
|-javascript
|-packs
|-[link to engine1.js pack files]
|-[link to engine2.js pack files]
|-engines
|- engine1
|-app
|-javascript
|-packs
|-engine1.js
|- engine2
|-app
|-javascript
|-packs
|-engine1.js
And this is how the webpacker.yml configuration
default: &default
source_path: app/javascript
source_entry_path: packs
public_output_path: packs
cache_path: tmp/cache/webpacker
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
resolved_paths: ['app/assets']
I think you'll want to do something like this:
additional_paths: ['engines']
Source: https://github.com/rails/webpacker#resolved
If you are adding Webpacker to an existing app that has most of the assets inside app/assets or inside an engine, and you want to share that with webpack modules, you can use the additional_paths option available in config/webpacker.yml. This lets you add additional paths that webpack should lookup when resolving modules:
Perhaps a better way to do what you mention is to take advantage of the webpacker folder structure.
Instead of creating links to files inside the "app/javascript/packs" folder, maybe you could reference them through the "index.js" files in those folders.
According to the documentation, webpacker will look for the "index.js" file inside each imported folder.
So you could modify the file structure to something like this:
-root
|
|-app
|-javascript
|-packs
|-engine1.js
|-engine2.js
|-engines
|- engine1
|-index.js
|-app
|-javascript
|-packs
|-engine1.js
|- engine2
|-index.js
|-app
|-javascript
|-packs
|-engine1.js
Create the files and import the respective folder
// app/javascript/packs/engine1.js
import 'engines/engine1'
// app/javascript/packs/engine2.js
import 'engines/engine2'
This will import the "index.js" file from the mentioned folder, and within that file you can import everything else you need from the "engineX" folder.
Then you can reference them as follows
<%# app/views/layouts/application.html.erb %>
<%= javascript_pack_tag 'engine1' %>
<%= javascript_pack_tag 'engine2' %>
All this can be done, without the need to modify the default Webpacker configuration

Rails: do not allow access to static asset directory without a trailing /

I would like to serve up a generated static website (containing documentation) from the Rails public/ directory. My directory structure looks like this:
`-- rails-root
| [...]
|-- public
| |-- assets
| | |-- favicon.png
| | |-- fonts
| | | `-- ...
| | |-- images
| | | `-- ...
| | |-- javascripts
| | | `-- ...
| | `-- stylesheets
| | `-- ...
| |-- documentation
| | |-- GLOSSARY.html
| | |-- index.html
| | `-- ...
I am copying my generated files to rails-root/public/documentation and everything is fine as long as I request it as http://<site>/documentation/ or http://<site>/documentation/index.html.
However, when I request http://<site>/documentation rails tries to be helpful and serves up my index.html page. All the links in the page are relative so serving it up from a different base (root) instead of its directory (documentation/) makes it impossible for it to load any assets, looks broken and prevents navigation from all links.
I've tried setting up a route to do a redirect in case someone requests http://<site>/documentation (without a trailing slash):
get '/documentation', :to => redirect('/documentation/index.html')
This does not work, I'm guessing because the public files take precedence over routing? I did try a bogus path just to validate that my routing code is correct and it worked:
get '/xxx', :to => redirect('/documentation/index.html')
I would like to either prevent rails from being helpful (I'm fine with a 404 for http://<site>/documentation as long as trailing / works; 404 is better than a broken page) or make the redirect. I am using Rails 4.2. Any ideas welcome!
The ActionDispatch::Static middleware is responsible for serving static content, and for this behavior of serving a directory even when accessed without trailing slash.
There doesn't seem to be a nice way to change this behavior without monkey patching or forking this middleware.
But, if you're ok with the overhead, a workaround is to observe that the request path/path_info is changed by ActionDispatch::Static and use this information to write a middleware that intercepts it and redirects directories without trailing slash:
module Rack
class RedirectStaticWithoutTrailingSlash
def initialize(app)
#app = app
end
def call(env)
request = Rack::Request.new(env)
original_path_info = request.path_info
response = #app.call(env)
updated_path_info = request.path_info
if serving_index_for_path_without_trailing_slash?(original_path_info, updated_path_info)
redirect_using_trailing_slash(original_path_info)
else
response
end
end
def serving_index_for_path_without_trailing_slash?(original_path_info, updated_path_info)
updated_path_info.end_with?('index.html') &&
original_path_info != updated_path_info &&
!original_path_info.end_with?('/')
end
def redirect_using_trailing_slash(path)
redirect("#{path}/")
end
def redirect(url)
[301, {'Location' => url, 'Content-Type' => 'text/html'}, ['Moved Permanently']]
end
end
end
This middleware will need to be configured to act before ActionDispatch in your rails configuration:
config.middleware.insert_before('ActionDispatch::Static', 'Rack::RedirectStaticWithoutTrailingSlash')
The disadvantage of this approach is that you still do all the work of reading the file and preparing the request, and since it's not using any kind of document behavior, it may break in future rails versions.

Resources