Browserify, shim different libraries in different browserify builds - gruntjs

I am using browserify + grunt to produce two separate JS outputs, a clientside and a serverside version of my app. eg.
gruntfile.js
browserify: {
server: {
files: { 'dist/server.js': ['src/serverside.js'], }
},
client: {
files: { 'dist/client.js': ['src/clientside.js'], }
}
}
Everything works nicely and I get 2 separate files.
Now I want my clientside app to use browserify-shim to reference some common libraries from a CDN.
eg.
"browserify-shim": {
"libThing": "global:LibThing"
},
"browserify": {
"transform": [
"browserify-shim"
]
}
The issue is that this shims it for both the client and server versions, on the server this stuff doesn't exist in global.
I want to apply this shim just to the client (not the server)
I have tried
"browserify-shim": {
"server": {
}
"client": {
"libThing": "global:LibThing"
}
},
"browserify": {
"transform": [
"browserify-shim"
]
}
but I cant seem to work out how to tell browserify to use a separate set of shims for each file.

Related

Is this the right way to get lite-server to recognize the "server.index" override in bs-config.js?

lite-server seems to be ignoring my attempt to override the default index.
I have bs-config.json:
{
"server": {
"baseDir": "src",
"index": "/index.3.html",
"routes": {
"/node_modules": "node_modules"
}
}
}
I am using lite-server version 2.3.0, like this:
> lite-server -c=bs-config.json
browser-sync config **
{ injectChanges: false,
files: [ './**/*.{html,htm,css,js}' ],
watchOptions: { ignored: 'node_modules' },
server:
{ baseDir: 'src',
middleware: [ [Function], [Function] ],
directory: true,
index: '/index.3.html',
routes: { '/node_modules': 'node_modules'
}
}
}
In the console log output above, it recognizes the bs-config.json index default of "index.3.html", however, when the browser requests "GET http://localhost", the console shows it is trying to serve index.html instead of index.3.html.
[Browsersync] Serving files from: src
[Browsersync] Watching files...
17.09.04 22:35:51 404 GET /index.html
I have also tried supplying bs-config.js:
"use strict";
module.exports = {
"server": {
"baseDir": "src",
index: "i/index.3.html",
"directory":true,
"routes": {
"/node_modules": "node_modules"
}
// middleware,: {
// // overrides the second middleware default with new settings
// 1: require('connect-history-api-fallback')({index: '/index.3.html', verbose: true})
// }
}
}
and running lite-server with:
> lite-server -c=bs-config.js
but the behavior is the same.
Question: how do I override bs-config's server.index for lite-server?
lite-server's config-default.js sets index in it's 2nd middleware "fallback" function. This seems to be overring bs-config setting.
So the solution seems to be, override the middleware to set index as desired.
bs-config.js:
module.exports = {
"server": {
"baseDir": "src",
"routes": {
"/node_modules": "node_modules"
},
middleware: {
// overrides the second middleware default with new settings
1: require('connect-history-api-fallback')({
index: '/index.3.html',
htmlAcceptHeaders: ['text/html', 'application/xhtml+xml'] // systemjs workaround})
}
}
}
Notes:
1. If a future version of lite-server changes it's default-config's middleware to put the index fallback in a different index position of the middleware function array, or to set different response headers, then this bs-config solution will need to be changed accordingly.
references:
Browserync Docs: https://browsersync.io/docs/options
lite-server: https://github.com/johnpapa/lite-server

Config for external (eg. bower) plugins

How can I use an configuration file (config.json) for easier grunt setup
I want to add/setup all needed plugins in my config.json and I want a seperated file for all Plugins or seperate FOlder for images
config.json
{
"images": {
"pluginA": [
"./faces/*.jpg"
],
"pluginB": [
"./corpes/*.jpg"
]
},
"javascript": {
"pluginA": [
"./faces/*.js"
],
"pluginB": [
"./corpes/*.js"
]
}
}
Gruntfile.js
plugins: grunt.file.readJSON('plugins_config.json')
jshint: {
development: {
files: {
**plugins.javascript**
}
}
}
desired output
dist/
images
pluginA
faces1.jpg
faces2.jpg
pluginB
corpes1.jpg
corpes2.jpg
javascript
pluginA.js
pluginB.js
styles
pluginA.css
pluginB.css
The way you usually access a grunt config is through the method grunt.config(key), so your json file is accessible through grunt.config('plugins').
Unfortunately the config object is initialized by grunt.initConfig, so you can't use it in the call to initConfig itself, which is what you need to do.
Your solution is to use a separate local variable outside initConfig, instead of a config:
module.exports = function(grunt) {
var plugins = grunt.file.readJSON('plugins_config.json');
// ...
grunt.initConfig({
jshint: {
development: {
files: {
src: plugins.javascript.pluginA,
}
}
},
// ...
});
};

How to watch over SASS to generate compressed as well as expanded or a combination of other styles?

I am using SASS.
But how to watch over SASS files (*.scss) from the root of the project folder to generate compressed (minified) as well as expanded (prettified) or a combination of other styles?
The reference in the SASS documentation does not seem to be (new) user friendly.
If (for whatever reason?) you need both output variants to exist at the same time, you could use a task runner like Grunt and define two different tasks and then run them both at once. You would need to specify two seperate output directories though, otherwise the second task would overwrite the result of the first task, like so:
sass: {
expanded: {
options: {
style: 'expanded'
},
files: {
'css-expanded/*.css': 'sass/*.scss'
}
}
compressed: {
options: {
style: 'compressed'
}
files: {
'css-compressed/*.css': 'sass/*.scss'
}
}
}
grunt.registerTask('compile': ['sass:expanded', 'sass:compressed']);
Presumably, you probably don't want/need both versions of the css output of the same time though, I guess you want expanded output during development for debugging, and compressed output when building your project?
If that's the case, you'd still need to specify two sass tasks/targets, but define a separate grunt task for each (but use the same output directory):
sass: {
expanded: {
options: {
style: 'expanded'
},
files: {
'css': 'sass/*.scss'
}
}
compressed: {
options: {
style: 'compressed'
}
files: {
'css': 'sass/*.scss'
}
}
}
grunt.registerTask('dev': ['sass:expanded']);
grunt.registerTask('build': ['sass:compressed'];
Edit:
If you want both version to live in the same output directory at the same time and the output css files don't need the same name for both versions, you could of course use a specific name for one of them *.css and *.min.css:
sass: {
expanded: {
options: {
style: 'expanded'
},
files: {
'css-expanded/*.css': 'sass/*.scss'
}
}
compressed: {
options: {
style: 'compressed'
}
files: {
'css-compressed/*.min.css': 'sass/*.scss'
}
}
}
grunt.registerTask('compile': ['sass:expanded', 'sass:compressed']);

Importance of names 'development' and 'production' in grunt-contrib-less

The example from grunt-contrib-less:
less: {
development: {
options: {
paths: ["assets/css"]
},
files: {
"path/to/result.css": "path/to/source.less"
}
},
production: {
options: {
paths: ["assets/css"],
plugins: [
new require('less-plugin-autoprefix')({browsers: ["last 2 versions"]}),
new require('less-plugin-clean-css')(cleanCssOptions)
],
modifyVars: {
imgPath: '"http://mycdn.com/path/to/images"',
bgColor: 'red'
}
},
files: {
"path/to/result.css": "path/to/source.less"
}
}
}
It provides two entries in the dictionary for less: development and production.
I don't know what to call these entries, perhaps smth like "sub-tasks for less".
Does the naming of these matter?
Is it possible to only run one of these. I've tried $ grunt less development, but that does not work.
The names matter and it's something you configure. These are like more like arguments than sub-tasks. Reference: http://gruntjs.com/api/grunt.task
Try grunt less:development

Is it possible to config an array in a nested object in grunt options?

I'm trying to write a small plugin and I want the user to be able to input an array into a nested object in grunt config, something like:
myTask: {
default: {
options: {
name: "someName"
deploy: {
envs: ["dev", "staging", "prod"]
}
}
}
}
In my task I'm trying to grab this.options.deploy.envs but it's undefined.
Not seen this style of plugin configuration before. Might be wiser to follow existing conventions for multi tasks:
myTask: {
deploy: {
options: {
name: "someName",
envs: ["dev", "staging", "prod"]
}
},
development: {
options: {
name: "othertarget",
envs: ["dev"]
}
}
}
In any case, you are missing a comma after "someName".

Resources