Skip to content

Commit

Permalink
make the .bootstraprc location customizable
Browse files Browse the repository at this point in the history
  • Loading branch information
Andrew Ralston committed Jul 29, 2016
1 parent 5c51234 commit 179d492
Show file tree
Hide file tree
Showing 28 changed files with 214 additions and 201 deletions.
32 changes: 29 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,14 +17,36 @@ To start development simply run:
npm start
```

It will run linters, clear directory with previous build, create new build and run watchers to re-build on every change. Sadly, but we can't use `npm link` feature in development process here because this command symlinks package folder, what makes impossible to resolve `bootstrap` packages in project's `npm_modules` folder. Instead of this just install `bootstrap-loader` locally:
It will run linters, clear directory with previous build, create new build and run watchers to re-build on every change.


### Using the Local Library
#### npm link
We can use the `npm link` feature in our development process if we reference full paths to our loader in webpack's config: `bootstrap-loader/lib/bootstrap.loader?extractStyles&configFilePath=${__dirname}/.bootstraprc!bootstrap-loader/no-op.js`. In order for this library to find the expected `bootstrap` version, you must also `npm link` the expected `bootstrap` and `extract-text-webpack-plugin` (assuming you are passing `extractStyles` to `boostrap.loader` e.g. `...
bootstrap.loader?extractStyles&...`) versions from your project's `node_modules` directory to your clone of this library.

#### Installing locally
If `npm link` doesn't work for you, just install `bootstrap-loader` locally:

```
cd my-test-project
npm install --save-dev ../path/to/local/bootstrap-loader
```

It is a pity, but you have to re-install `bootstrap-lodaer` on every change.
Note that if you install `bootstrap-loader` locally, you have to re-install it on every change.

#### Testing changes to the repo
Make sure to write new tests for your changes. Currently the test suite is light, please help us flesh it out. Run the tests with `npm test`.

You will also want to run the example implementations to ensure they work as expected with your changes. To test the examples,

```
cd examples/basic
npm install --save-dev ../..
npm run bs4:customlocation
```

Ensure your changes don't break any of the examples before you publish your PR.

### Build
To create a build run:
Expand All @@ -42,7 +64,11 @@ To lint your code run:
npm run lint
```

Shame on us, but we don't have any tests here yet. We will be happy, if you can give us a hand with it.
To test your code run:

```
npm run test
```

## How loader works
There are 2 entry points: `./loader.js` & `./extractStyles.js`. These are the dummy loaders, which apply real loader to dummy `no-op.js` file. The source of the real loader is located in `./src/bootstrap.loader.js`. Before exploring things in it, check out `./src/bootstrap.config.js` to figure out how we handle default / user config files & gather options for loader.
Expand Down
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,11 @@ Or add `bootstrap-loader` as [a module in an entry point](https://webpack.github
entry: [ 'bootstrap-loader', './app' ]
```

Config is optional. It can be placed in root dir with name `.bootstraprc`. You can write it in `YAML` or `JSON` formats. Take a look at the default config files for [Bootstrap 3](.bootstraprc-3-default) and [Bootstrap 4](.bootstraprc-4-default). Note, we recommend using a configuration or else you might pick up unwanted upgrades, such as when we make Bootstrap 4 the default. Config options don't fall back on the defaults once a config file is present. Be sure not to delete config options. To start with a custom config, copy over a default config file as a starting point.
Config is optional. If used, by default it should be placed in your project's root dir with name `.bootstraprc`. You can write it in `YAML` or `JSON` formats. Take a look at the default config files for [Bootstrap 3](.bootstraprc-3-default) and [Bootstrap 4](.bootstraprc-4-default). Note, we recommend using a configuration or else you might pick up unwanted upgrades, such as when we make Bootstrap 4 the default. Config options don't fall back on the defaults once a config file is present. Be sure not to delete config options. To start with a custom config, copy over a default config file as a starting point.

If the default location doesn't work for you (e.g. you want to create multiple bootstrap configs for branding variations or you symlink your npm_modules directory), you may pass the **absolute path** of the `.bootstraprc` file to the loader in your webpack config, e.g. `bootstrap-loader/lib/bootstrap.loader?extractStyles&configFilePath=${__dirname}/.bootstraprc!bootstrap-loader/no-op.js`.

Note that :`__dirname` is a [global variable](https://nodejs.org/docs/latest/api/globals.html#globals_dirname) that Node sets for us. It is "the name of the directory that the currently executing script resides in."

```yaml
---
Expand Down Expand Up @@ -105,6 +109,7 @@ If no config provided, default one for Bootstrap 3 will be used.
Check out example apps in [`examples/`](examples) folder:

* Basic usage: [examples/basic](examples/basic)
* See the `npm run bs4:customlocation` tasks for examples on how to pass your .bootstraprc config.
* With CSS Modules: [examples/css-modules](examples/css-modules) (This example shows off hot reloading with Babel 6 as well!)

## Common Options for Bootstrap 3 and 4
Expand Down
Empty file modified examples/basic/.babelrc
100644 → 100755
Empty file.
125 changes: 0 additions & 125 deletions examples/basic/.bootstraprc

This file was deleted.

Empty file modified examples/basic/.bootstraprc-3-example
100644 → 100755
Empty file.
Empty file modified examples/basic/.bootstraprc-4-example
100644 → 100755
Empty file.
Empty file modified examples/basic/.eslintignore
100644 → 100755
Empty file.
Empty file modified examples/basic/.eslintrc
100644 → 100755
Empty file.
3 changes: 3 additions & 0 deletions examples/basic/.gitignore
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -216,3 +216,6 @@ $RECYCLE.BIN/

# Windows shortcuts
*.lnk

# the npm run ... commands can create this file but we don't want it checked in
/.bootstraprc
Empty file modified examples/basic/README.md
100644 → 100755
Empty file.
Empty file modified examples/basic/app/markup/bootstrap-dev.html
100644 → 100755
Empty file.
Empty file modified examples/basic/app/markup/bootstrap-prod.html
100644 → 100755
Empty file.
Empty file modified examples/basic/app/scripts/app.js
100644 → 100755
Empty file.
Empty file modified examples/basic/app/styles/app.scss
100644 → 100755
Empty file.
Empty file modified examples/basic/app/styles/bootstrap/customizations.scss
100644 → 100755
Empty file.
Empty file modified examples/basic/app/styles/bootstrap/pre-customizations.scss
100644 → 100755
Empty file.
Empty file modified examples/basic/app/styles/fonts/OpenSans-Light.ttf
100644 → 100755
Empty file.
17 changes: 11 additions & 6 deletions examples/basic/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,19 @@
"scripts": {
"start": "nodemon --watch app/markup --ext html server.dev.js",
"clean": "rm -rf public/",
"cleanrc": "rm .bootstraprc || echo 'no .bootstraprc file to delete'",
"build": "npm run clean && webpack --config webpack.prod.config.js",
"prod": "npm run build && nodemon --watch app/markup --ext html server.prod.js",
"bs3": "rm .bootstraprc && cp .bootstraprc-3-example .bootstraprc",
"bs4": "rm .bootstraprc && cp .bootstraprc-4-example .bootstraprc",
"prod": "nodemon --watch app/markup --ext html server.prod.js",
"bs3": "cp -f .bootstraprc-3-example .bootstraprc",
"bs4": "cp -f .bootstraprc-4-example .bootstraprc",
"bs3:customlocation": "npm run cleanrc && nodemon --watch app/markup --ext html server.dev.js --bootstraprc-location=.bootstraprc-3-example",
"bs4:customlocation": "npm run cleanrc && nodemon --watch app/markup --ext html server.dev.js --bootstraprc-location=.bootstraprc-4-example",
"bs3:dev": "npm run bs3 && npm start",
"bs4:dev": "npm run bs4 && npm start",
"bs3:prod": "npm run bs3 && npm run prod",
"bs4:prod": "npm run bs4 && npm run prod"
"bs3:prod": "npm run bs3 && npm run build && npm run prod",
"bs4:prod": "npm run bs4 && npm run build && npm run prod",
"bs3:customlocation:prod": "npm run cleanrc && npm run build -- --bootstraprc-location=.bootstraprc-3-example && npm run prod",
"bs4:customlocation:prod": "npm run cleanrc && npm run build -- --bootstraprc-location=.bootstraprc-4-example && npm run prod"
},
"repository": {
"type": "git",
Expand Down Expand Up @@ -55,7 +60,7 @@
"font-awesome-loader": "^1.0.0",
"imports-loader": "^0.6.5",
"node-sass": "^3.4.2",
"nodemon": "^1.8.1",
"nodemon": "^1.9.2",
"postcss-loader": "^0.8.1",
"resolve-url-loader": "^1.4.3",
"sass-loader": "^3.1.1",
Expand Down
Empty file modified examples/basic/server.dev.js
100644 → 100755
Empty file.
Empty file modified examples/basic/server.prod.js
100644 → 100755
Empty file.
46 changes: 46 additions & 0 deletions examples/basic/webpack.bootstrap.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
'use strict';
const fs = require('fs');

function getBootstraprcCustomLocation() {
const matchedArgument = process.argv.find(val => val.includes('--bootstraprc-location'));
return matchedArgument && matchedArgument.split('=')[1];
}

const bootstraprcCustomLocation = getBootstraprcCustomLocation();

let defaultBootstraprcFileExists;

try {
fs.statSync('./.bootstraprc');
defaultBootstraprcFileExists = true;
} catch (e) {
defaultBootstraprcFileExists = false;
}

if (!bootstraprcCustomLocation && !defaultBootstraprcFileExists) {
throw new Error('This script requires a \'bootstraprc-location\' arg or a ./.boostraprc file in the root.');
}

// DEV and PROD have slightly different configurations
let bootstrapDevEntryPoint;
if (bootstraprcCustomLocation) {
bootstrapDevEntryPoint = 'bootstrap-loader/lib/bootstrap.loader?' +
`configFilePath=${__dirname}/${bootstraprcCustomLocation}` +
'!bootstrap-loader/no-op.js';
} else {
bootstrapDevEntryPoint = 'bootstrap-loader';
}

let bootstrapProdEntryPoint;
if (bootstraprcCustomLocation) {
bootstrapProdEntryPoint = 'bootstrap-loader/lib/bootstrap.loader?extractStyles' +
`&configFilePath=${__dirname}/${bootstraprcCustomLocation}` +
'!bootstrap-loader/no-op.js';
} else {
bootstrapProdEntryPoint = 'bootstrap-loader/extractStyles';
}

module.exports = {
dev: bootstrapDevEntryPoint,
prod: bootstrapProdEntryPoint,
};
6 changes: 5 additions & 1 deletion examples/basic/webpack.dev.config.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,18 @@
const webpack = require('webpack');
const path = require('path');
const autoprefixer = require('autoprefixer');
const bootstrapEntryPoints = require('./webpack.bootstrap.config.js');

// eslint-disable-next-line no-console
console.log(`=> bootstrap-loader configuration: ${bootstrapEntryPoints.dev}`);

module.exports = {

entry: [
'webpack-hot-middleware/client',
'tether',
'font-awesome-loader',
'bootstrap-loader',
bootstrapEntryPoints.dev,
'./app/scripts/app',
],

Expand Down
6 changes: 5 additions & 1 deletion examples/basic/webpack.prod.config.js
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,18 @@ const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const path = require('path');
const autoprefixer = require('autoprefixer');
const bootstrapEntryPoints = require('./webpack.bootstrap.config.js');

// eslint-disable-next-line no-console
console.log(`=> bootstrap-loader configuration: ${bootstrapEntryPoints.prod}`);

module.exports = {

// For production build we want to extract CSS to stand-alone file
// Provide `extractStyles` param and `bootstrap-loader` will handle it
entry: [
'font-awesome-loader',
'bootstrap-loader/extractStyles',
bootstrapEntryPoints.prod,
'tether',
'./app/scripts/app',
],
Expand Down
10 changes: 10 additions & 0 deletions node_package/scripts/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/sh

echo "Running JS tests in node"
$(npm bin)/babel-tape-runner node_package/tests/*.js | $(npm bin)/tap-spec
# $(npm bin)/babel-tape-runner node_package/tests/*.js | $(npm bin)/faucet

# If we want to run tests in the browser
# echo "Running JS tests in browser"
# $(npm bin)/browserify -t babelify node_package/tests/*.js | tape-run | $(npm bin)/faucet

10 changes: 10 additions & 0 deletions node_package/tests/configCreation.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import test from 'tape';
import { userConfigFileExists } from '../../src/bootstrap.config.js';

test('userConfigFileExists returns true for files that exist', (assert) => {
const result = userConfigFileExists(`${__dirname}/configCreation.test.js`);

assert.plan(1);
assert.equal(result, true);
assert.end();
});
6 changes: 5 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"description": "Boostrap for Webpack",
"main": "loader.js",
"scripts": {
"test": "node_package/scripts/test",
"start": "npm run lint && npm run clean && npm run dev",
"dev": "babel --watch --out-dir lib src",
"build": "babel --out-dir lib src",
Expand Down Expand Up @@ -55,7 +56,10 @@
"babel": "^6.0.15",
"babel-cli": "^6.1.4",
"babel-preset-es2015": "^6.1.4",
"babel-tape-runner": "^2.0.1",
"eslint": "^1.10.3",
"eslint-config-airbnb": "^2.0.0"
"eslint-config-shakacode": "^5.0.0",
"tap-spec": "^4.1.1",
"tape": "^4.5.1"
}
}
Loading

0 comments on commit 179d492

Please sign in to comment.