Skip to content

Commit de150c7

Browse files
authored
Merge pull request #18 from FoxComm/feature/theming
implemented theming support via resources overriding
2 parents ab9d8ff + 8832c0e commit de150c7

33 files changed

Lines changed: 926 additions & 95 deletions

.gitignore

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1-
/lib
1+
/build
22
/node_modules
3-
*.log
3+
*.log
4+
/public

.npmignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@
55
/src/opt
66
/src/paragons
77
/src/types
8+
/packages

Makefile

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,58 @@
33
JS_FILES = $(shell find ./src -name "*.js" -o -name "*.jsx")
44
PRETTIER_OPTIONS = --single-quote --trailing-comma es5 --print-width 120
55

6+
.PHONY: setup
67
setup: clean
78
yarn --pure-lockfile
89

10+
.PHONY: build-theme
11+
build-theme:
12+
./node_modules/.bin/gulp
13+
14+
.PHONY: build
915
build:
10-
yarn build
16+
make build-theme
17+
THEME=tpg make build-theme
18+
make prepare-package
1119

20+
.PHONY: clean
1221
clean:
1322
rm -rf ./node_modules
14-
rm -rf ./lib/*
23+
rm -rf ./build
24+
25+
.PHONY: prepare-package
26+
prepare-package:
27+
cp package.json README.md .npmrc postcss.config.js build/
28+
cp src/index.js build/exports.js
1529

30+
.PHONY: test
1631
test:
1732
yarn flow
1833

34+
.PHONY: fmt
1935
fmt:
2036
./node_modules/.bin/prettier $(PRETTIER_OPTIONS) --write $(JS_FILES)
2137

22-
.PHONY: setup build clean test fmt
38+
.PHONY: publish
39+
publish: build
40+
npm publish ./build --access restricted
41+
42+
43+
.PHONY: build-sg
44+
build-sg:
45+
NODE_PATH=./src ./node_modules/.bin/styleguidist build --config styleguide.config.js
46+
47+
.PHONY: build-sg-tpg
48+
build-sg-tpg:
49+
THEME=tpg NODE_PATH=./src ./node_modules/.bin/styleguidist build --config styleguide.config.js
50+
51+
.PHONY: build-styleguides
52+
build-styleguides: build-sg build-sg-tpg
53+
54+
.PHONY: sg
55+
sg:
56+
NODE_PATH=./src ./node_modules/.bin/styleguidist server --config styleguide.config.js
57+
58+
.PHONY: sg-tpg
59+
sg-tpg:
60+
THEME=tpg NODE_PATH=./src ./node_modules/.bin/styleguidist server --config styleguide.config.js

README.md

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,23 @@ Installation
66
yarn add @foxcomm/storefront-react
77
```
88

9+
Following resources should be included in your project:
10+
11+
#### css styles
12+
- `node_modules/@foxcomm/storefront-react/lib/bundle.css` css styles, include to your css bundle
13+
- `node_modules/@foxcomm/storefront-react/lib/sprite.svg` svg icons bundled into the single sprite,
14+
should be included as is to the html
15+
16+
917
Usage
1018

1119
At first you will need include storefront css located in
12-
`@foxcomm/sf-react/lib/bundle.css` to your project.
20+
to your project.
1321

1422
Later you can use storefront react components, like in this example:
1523

1624
```
17-
import SelectBox from '@foxcomm/storefront-react/lib/components/selectbox/selectbox';
25+
import { SelectBox } from '@foxcomm/storefront-react';
1826
//
1927
// later in component:
2028
render() {
@@ -23,3 +31,5 @@ render() {
2331
2432
```
2533

34+
You can optimize bundle size via `@foxcomm/storefront-react-optimize-imports` package.
35+
See [README](./packages/storefront-react-optimize-imports/README.md) for details.

gulpfile.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const gulp = require('gulp');
22
require('./tasks/css');
33
require('./tasks/sprites');
4+
require('./tasks/js');
45

5-
gulp.task('default', ['css', 'sprites']);
6+
gulp.task('default', ['css', 'sprites', 'js']);

opt/linkfs.js

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
const path = require('path');
2+
const fs = require('fs');
3+
const _ = require('lodash');
4+
5+
6+
const methods = [
7+
'rename',
8+
'renameSync',
9+
'truncate',
10+
'truncateSync',
11+
'chown',
12+
'chownSync',
13+
'lchown',
14+
'lchownSync',
15+
'chmod',
16+
'chmodSync',
17+
'lchmod',
18+
'lchmodSync',
19+
'stat',
20+
'lstat',
21+
'statSync',
22+
'lstatSync',
23+
'link',
24+
'linkSync',
25+
'symlink',
26+
'symlinkSync',
27+
'readlink',
28+
'readlinkSync',
29+
'realpath',
30+
'realpathSync',
31+
'unlink',
32+
'unlinkSync',
33+
'rmdir',
34+
'rmdirSync',
35+
'mkdir',
36+
'mkdirSync',
37+
'readdir',
38+
'readdirSync',
39+
'open',
40+
'openSync',
41+
'utimes',
42+
'utimesSync',
43+
'readFile',
44+
'readFileSync',
45+
'writeFile',
46+
'writeFileSync',
47+
'appendFile',
48+
'appendFileSync',
49+
'watchFile',
50+
'unwatchFile',
51+
'watch',
52+
'exists',
53+
'existsSync',
54+
'access',
55+
'accessSync',
56+
'createReadStream',
57+
'createWriteStream'
58+
];
59+
60+
const originalFs = fs;
61+
const existsSync = fs.existsSync;
62+
63+
function linkfs(fs, rewrites, finalMethods = methods) {
64+
const resolvedRewrites = Object.create(null);
65+
_.each(rewrites, (value, from) => {
66+
resolvedRewrites[path.resolve(from)] = path.resolve(value);
67+
});
68+
69+
// Rewrite the path of the selected methods.
70+
const linkedfs = {};
71+
_.each(finalMethods, method => {
72+
const func = fs[method];
73+
linkedfs[method] = function(filepath, ...args) {
74+
filepath = path.resolve(filepath);
75+
76+
for (let from in resolvedRewrites) {
77+
if (filepath.indexOf(from) === 0) {
78+
const newPath = filepath.replace(from, resolvedRewrites[from]);
79+
if (existsSync.call(originalFs, newPath)) {
80+
filepath = newPath;
81+
break;
82+
}
83+
}
84+
}
85+
86+
return func.call(fs, filepath, ...args);
87+
};
88+
});
89+
90+
// Just proxy the rest of the methods
91+
for (let method in fs) {
92+
const func = fs[method];
93+
if ((typeof func == 'function') && !linkedfs[method]) {
94+
linkedfs[method] = fs[method].bind(fs);
95+
}
96+
}
97+
98+
return linkedfs;
99+
}
100+
101+
102+
module.exports = linkfs;

override-fs.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
2+
const fs = require('fs');
3+
const path = require('path');
4+
const unionfs = require('unionfs');
5+
const linkfs = require('./opt/linkfs');
6+
7+
const themeName = process.env.THEME;
8+
9+
const ReadStream = fs.ReadStream;
10+
const WriteStream = fs.WriteStream;
11+
12+
function override(themeName = 'peacock') {
13+
const linkedfs = linkfs(fs, {
14+
[path.resolve('./src')]: path.resolve(`./themes/${themeName}`)
15+
});
16+
17+
unionfs
18+
.use(fs)
19+
.use(linkedfs)
20+
.replace(fs);
21+
22+
fs.ReadStream.prototype = ReadStream.prototype;
23+
fs.WriteStream.prototype = WriteStream.prototype;
24+
}
25+
26+
override(themeName);
27+

package.json

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,11 @@
11
{
22
"name": "@foxcomm/storefront-react",
3-
"version": "1.4.0",
3+
"version": "1.5.0",
44
"description": "FoxCommerce Storefront React UI Library",
55
"main": "lib/index.js",
66
"scripts": {
7-
"build-gulp": "gulp",
8-
"build-js": "babel src -d lib",
9-
"build": "npm run build-gulp && npm run build-js",
10-
"prepublish": "npm run build",
11-
"sg": "NODE_PATH=./src styleguidist server --config styleguide.config.js",
7+
"build": "make build",
8+
"prepublish": "make build",
129
"flow": "flow check"
1310
},
1411
"publishConfig": {
@@ -31,7 +28,6 @@
3128
"homepage": "https://github.com/FoxComm/storefront.react.js#readme",
3229
"devDependencies": {
3330
"@foxcomm/babel-plugin-react-stylenames": "^3.1.0",
34-
"babel-cli": "^6.24.1",
3531
"babel-eslint": "^7.2.3",
3632
"babel-loader": "^7.0.0",
3733
"babel-plugin-module-resolver": "^2.7.1",
@@ -54,6 +50,7 @@
5450
"fs-extra": "^3.0.1",
5551
"gulp": "^3.9.1",
5652
"gulp-add-src": "^0.2.0",
53+
"gulp-babel": "^6.1.2",
5754
"gulp-concat": "^2.6.1",
5855
"gulp-postcss": "^7.0.0",
5956
"gulp-sourcemaps": "^2.6.0",
@@ -70,6 +67,8 @@
7067
"react-styleguidist": "^5.2.1",
7168
"style-loader": "^0.17.0",
7269
"through2": "^2.0.3",
70+
"unionfs": "^0.0.9",
71+
"vinyl-file": "^3.0.0",
7372
"webpack": "^3.0.0",
7473
"webpack-svgstore-plugin": "^4.0.1"
7574
},

packages/storefront-react-optimize-imports/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@foxcomm/storefront-react-optimize-imports",
3-
"version": "1.2.0",
3+
"version": "1.3.0",
44
"description": "Optimize imports for storefront-react package in order to get smaller bundle size",
55
"main": "src/index.js",
66
"publishConfig": {

packages/storefront-react-optimize-imports/src/index.js

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const rootPackage = require(parentPackagePath);
2626
if (rootPackage.name === pkgName) {
2727
importsEntrypoint = path.join(path.dirname(parentPackagePath), 'src/index.js');
2828
} else {
29-
importsEntrypoint = path.join(path.dirname(parentPackagePath), 'node_modules', pkgName, 'src/index.js');
29+
importsEntrypoint = path.join(path.dirname(parentPackagePath), 'node_modules', pkgName, 'exports.js');
3030
}
3131

3232
const importsCode = fs.readFileSync(importsEntrypoint).toString();
@@ -60,19 +60,21 @@ function transformToComponents(importsAst) {
6060
const components = transformToComponents(importsAst);
6161
exports.components = components;
6262

63+
const pkgRe = /^\@foxcomm\/storefront-react\/[^\/]+$/;
64+
6365
function plugin(_ref) {
6466
const t = _ref.types;
6567

6668
return {
6769
visitor: {
6870
ImportDeclaration(path) {
6971
const { node } = path;
70-
if (node.source.value == pkgName) {
72+
if (pkgRe.test(node.source.value)) {
7173
const newImports = node.specifiers.map(decl => {
7274
const name = decl.imported.name;
7375
if (name in components) {
7476
const entry = components[name];
75-
const source = t.stringLiteral(`${pkgName}/lib${entry.path}`);
77+
const source = t.stringLiteral(`${node.source.value}${entry.path}`);
7678
let specifier;
7779
if (entry.isDefault) {
7880
specifier = t.importDefaultSpecifier(t.identifier(decl.local.name));

0 commit comments

Comments
 (0)