This repository has been archived by the owner on Aug 5, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 43
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
gluestick-plugin-no-fouc: Remove Flash of Unstyled Content in develop…
…ment (#1036) * check for style assets in development also * initial impl of no-fouc plugin * no-fouc plugin refactor * no-fouc plugin test * no-fouc plugin readme * removed insignificant test case * fix typo in no-fouc plugin's README * fix typo in no-fouc plugin's README
- Loading branch information
1 parent
8cb822d
commit 13086d0
Showing
8 changed files
with
227 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
{ | ||
"presets": [ | ||
["env", { | ||
"targets": { | ||
"node": 6.3 | ||
} | ||
}], | ||
"stage-0" | ||
] | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
**/__mocks__/** | ||
**/__tests__/** | ||
src/** | ||
coverage/** | ||
.babelrc |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
# `gluestick-plugin-no-fouc` | ||
|
||
Removes Flash of Unstyled Content (FOUC) in development. | ||
|
||
## How it works | ||
All styles will be extracted to css file using `ExtractTextWebpackPlugin` then, the file will be linked by server/renderer and added to `<head>` element. It sits side-by-side with `style-loader`, so you can still use HMR. | ||
|
||
__In production this plugin does nothing.__ | ||
|
||
## How to use | ||
* Install plugin | ||
``` | ||
npm install --save gluestick-plugin-no-fouc | ||
``` | ||
* Define (and configure) plugin in `src/gluestick.plugins.js`: | ||
```javascript | ||
export default [ | ||
'gluestick-plugin-no-fouc' | ||
] | ||
|
||
// or | ||
|
||
export default [ | ||
{ | ||
plugin: 'gluestick-plugin-no-fouc', | ||
options: { | ||
filename: '[name].fouc-reducer.css' | ||
}, | ||
}, | ||
] | ||
``` | ||
|
||
## Configuration | ||
- `filename`: `string` (default: `[name]-[contenthash].init-no-fouc.css`) - name of the file to which all styles will be extracted, can contain webpack tokens eg: `[name]`, `[hash]`, `[contenthash]` and so on |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
{ | ||
"name": "gluestick-plugin-no-fouc", | ||
"version": "1.11.0", | ||
"description": "Remove FOUC by extracting css into file and linking them to renderer page in development", | ||
"main": "build/config.js", | ||
"homepage": "https://github.com/TrueCar/gluestick", | ||
"bugs": "https://github.com/TrueCar/gluestick/issues", | ||
"license": "MIT", | ||
"scripts": { | ||
"test": "jest", | ||
"test-coverage": "jest --coverage" | ||
}, | ||
"author": "Todd Williams <toddsurfs@icloud.com>", | ||
"repository": { | ||
"type": "git", | ||
"url": "git@github.com:TrueCar/gluestick.git" | ||
}, | ||
"jest": { | ||
"notify": true, | ||
"testRegex": ".*/__tests__/.*\\.test\\.js$" | ||
}, | ||
"peerDependencies": { | ||
"gluestick": "1.11.0", | ||
"extract-text-webpack-plugin": "2.x" | ||
}, | ||
"devDependencies": { | ||
"babel-preset-es2015": "6.22.0", | ||
"babel-preset-stage-0": "6.22.0", | ||
"extract-text-webpack-plugin": "2.1.2", | ||
"gluestick": "1.11.0", | ||
"jest": "18.1.0" | ||
} | ||
} |
101 changes: 101 additions & 0 deletions
101
packages/gluestick-plugin-no-fouc/src/__tests__/config.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
jest.mock('extract-text-webpack-plugin', () => { | ||
let calledTimes = 0; | ||
class ExtractTestWebpackPlugin { | ||
constructor(opts) { | ||
this.opts = opts; | ||
calledTimes++; | ||
} | ||
} | ||
ExtractTestWebpackPlugin.extract = v => v; | ||
ExtractTestWebpackPlugin.calledTimes = () => calledTimes; | ||
return ExtractTestWebpackPlugin; | ||
}); | ||
|
||
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin'); | ||
const noFoucPlugin = require('../config'); | ||
|
||
const nodeEnv = 'test'; | ||
|
||
describe('gluestick no-fouc plugin', () => { | ||
describe('in production', () => { | ||
it('should do nothing', () => { | ||
process.env.NODE_ENV = 'production'; | ||
const webpackClientConfig = { | ||
plugins: [], | ||
module: { | ||
rules: [{ | ||
test: /\.(css)$/, | ||
use: [], | ||
}], | ||
}, | ||
}; | ||
const { postOverwrites } = noFoucPlugin(); | ||
expect(postOverwrites.clientWebpackConfig(webpackClientConfig)).toEqual(webpackClientConfig); | ||
expect(ExtractTextWebpackPlugin.calledTimes()).toBe(0); | ||
process.env.NODE_ENV = nodeEnv; | ||
}); | ||
}); | ||
|
||
describe('in development', () => { | ||
beforeEach(() => { | ||
process.env.NODE_ENV = nodeEnv; | ||
}); | ||
|
||
it('should modify scss/css rules and add a plugin', () => { | ||
const webpackClientConfig = { | ||
plugins: [], | ||
module: { | ||
rules: [{ | ||
test: /\.(scss)$/, | ||
use: [ | ||
'style-loader', | ||
'css-loader', | ||
'sass-loader', | ||
], | ||
}, { | ||
test: /\.(css)$/, | ||
use: [ | ||
'style-loader', | ||
'css-loader', | ||
], | ||
}], | ||
}, | ||
}; | ||
const { postOverwrites } = noFoucPlugin(); | ||
const modifiedConfig = postOverwrites.clientWebpackConfig(webpackClientConfig); | ||
expect(modifiedConfig.plugins.length).toBe(1); | ||
expect(modifiedConfig.plugins[0].opts.filename).toBeDefined(); | ||
expect(modifiedConfig.plugins[0].opts.allChunks).toBeTruthy(); | ||
expect(modifiedConfig.module.rules[0].use).toEqual([ | ||
{ loader: 'style-loader' }, | ||
{ | ||
fallback: 'style-loader', | ||
remove: false, | ||
use: [ | ||
'css-loader', | ||
'sass-loader', | ||
], | ||
}, | ||
]); | ||
expect(modifiedConfig.module.rules[1].use).toEqual([ | ||
{ loader: 'style-loader' }, | ||
{ | ||
fallback: 'style-loader', | ||
remove: false, | ||
use: [ | ||
'css-loader', | ||
], | ||
}, | ||
]); | ||
}); | ||
|
||
it('shuld use provided filename from options', () => { | ||
const filename = 'my-filename.css'; | ||
const { postOverwrites } = noFoucPlugin({ filename }); | ||
expect(postOverwrites.clientWebpackConfig({ | ||
plugins: [], | ||
module: { rules: [] }, | ||
}).plugins[0].opts.filename).toEqual(filename); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
const ExtractTextPlugin = require('extract-text-webpack-plugin'); | ||
|
||
const modifyLoader = ({ rules }, test) => { | ||
const styleLoader = { loader: 'style-loader' }; | ||
const index = rules.findIndex(rule => rule.test.source === test.source); | ||
if (index >= 0) { | ||
const loaders = rules[index].use; | ||
// eslint-disable-next-line no-param-reassign | ||
rules[index].use = [styleLoader].concat(ExtractTextPlugin.extract({ | ||
fallback: loaders[0], | ||
use: loaders.slice(1), | ||
remove: false, | ||
})); | ||
} | ||
}; | ||
|
||
const clientWebpackConfig = (filename = '[name]-[contenthash].init-no-fouc.css') => config => { | ||
if (process.env.NODE_ENV !== 'production') { | ||
modifyLoader(config.module, /\.(scss)$/); | ||
modifyLoader(config.module, /\.(css)$/); | ||
config.plugins.push( | ||
new ExtractTextPlugin({ | ||
filename, | ||
allChunks: true, | ||
}), | ||
); | ||
} | ||
return config; | ||
}; | ||
|
||
module.exports = (options = {}) => ({ | ||
postOverwrites: { | ||
clientWebpackConfig: clientWebpackConfig(options.filename), | ||
}, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters