diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..8e445f8 --- /dev/null +++ b/.babelrc @@ -0,0 +1,6 @@ +{ + "presets": ["es2015"], + "plugins": [ + "syntax-trailing-function-commas" + ] +} diff --git a/.eslintrc b/.eslintrc index e4a6dba..9dd0540 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,18 +1,29 @@ +extends: 'airbnb-base' +env: + node: true + browser: false rules: - # specify whether double or single quotes should be used - quotes: [2, "single", "avoid-escape"] - # controls location of Use Strict Directives - strict: [2, "global"] + no-multiple-empty-lines: + - 2 + - max: 1 - # disallow use of multiple spaces - no-multi-spaces: [0] + # Force trailing commas as this promotes smaller diffs. However + # we want to disable on functions, as this is invalid syntax (without any + # transpilation) + comma-dangle: + - 2 + - arrays: only-multiline + objects: only-multiline + imports: only-multiline + exports: only-multiline + functions: never - # enforces spacing between keys and values in object literal properties - key-spacing: [0] - # allow just one var statement per function (off by default) - one-var: [2, {uninitialized: "always", initialized: "never"}] + + # ------------------- + # Static Complexity Rules: they guide us to write better code. + # ------------------- # specify the maximum number of statement allowed in a function # (off by default) @@ -31,3 +42,11 @@ rules: # specify the maximum depth callbacks can be nested (off by default) max-nested-callbacks: [1, 2] + + # Forbid the import of external modules that are not declared in the + # package.json's dependencies, devDependencies, optionalDependencies or + # peerDependencies + # (note: we disable this rule because packages inside `src` behave like + # aliases: e.g.: require('elements/foo') works). + import/no-extraneous-dependencies: [0] + import/no-unresolved: [0] diff --git a/.gitignore b/.gitignore index 1676a24..7940c4c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ node_modules .DS_Store *.orig .tmp +npm-debug.log diff --git a/readme.md b/README.md similarity index 96% rename from readme.md rename to README.md index aa22365..c1d6133 100644 --- a/readme.md +++ b/README.md @@ -1,12 +1,11 @@ # Skeleton - styleguide This project is about creating templates to display a frontend styleguide ---- - + --- ## Instructions to run the project ### Prerequisites -You will need +You will need - [node.js](http://nodejs.org) to run the skeleton. ### Build diff --git a/gulp/.eslintrc b/gulp/.eslintrc deleted file mode 100644 index 8ea5f03..0000000 --- a/gulp/.eslintrc +++ /dev/null @@ -1,2 +0,0 @@ -env: - node: true diff --git a/gulp/config.js b/gulp/config.js index 641a6a1..7acf15b 100644 --- a/gulp/config.js +++ b/gulp/config.js @@ -1,108 +1,105 @@ -'use strict'; -var argv = require('yargs').argv; -var path = require('path'); +const argv = require('yargs').argv; +const path = require('path'); -module.exports = function (dest) { - var root = path.join(__dirname, '..'); - var basePaths = { - root: path.join(__dirname, '..'), - src: root + '/src/', - content: root + '/content/', - assets: root + '/assets/', - dest: root + '/build/', - tmp: root + '/.tmp/' +module.exports = (dest) => { + const basePaths = { + root: path.join(__dirname, '..'), + src: 'src/', + content: 'content/', + assets: 'assets/', + dest: 'build/', + tmp: '.tmp/', }; - // This helps overwriting the target destination - // For changing .src folders you need to overwrite by hand: - // conf = require('thisConfig'); - // conf.paths.content.src = 'anotherFolder' if (dest != undefined) { basePaths.dest = dest; } - var languages = ['en']; + const languages = ['en']; - var paths = { + const paths = { scripts: { - src: basePaths.src + 'scripts/', - dest: basePaths.dest + 'js/' + src: `${basePaths.src}scripts/`, + dest: `${basePaths.dest}js/`, }, styles: { - src: basePaths.src + 'styles/', - dest: basePaths.dest + 'css/' + src: `${basePaths.src}styles/`, + dest: `${basePaths.dest}css/`, }, content: { - src: basePaths.content + 'data/', - dest: basePaths.dest + 'content/data/' + src: `${basePaths.content}data/`, + dest: `${basePaths.dest}content/data/` }, pages: { - src: basePaths.src + 'pages/', - dest: basePaths.dest + src: `${basePaths.src}pages/`, + dest: basePaths.dest, }, layouts: { - src: basePaths.src + 'layouts/' + src: `${basePaths.src}layouts/`, }, images: { - src: basePaths.content + 'images/', - dest: basePaths.dest + 'content/images/' + src: `${basePaths.content}images/`, + dest: `${basePaths.dest}content/images/`, }, logos: { - src: basePaths.assets + 'logos/', - dest: basePaths.dest + 'assets/logos/' + src: `${basePaths.assets}logos/`, + dest: `${basePaths.dest}assets/logos/`, }, favicons: { - src: basePaths.assets + 'favicons/', - dest: basePaths.dest + src: `${basePaths.assets}favicons/`, + dest: basePaths.dest, }, fonts: { - src: basePaths.assets + 'fonts/', - dest: basePaths.dest + 'assets/fonts/' - } + src: `${basePaths.assets}fonts/`, + dest: `${basePaths.dest}assets/fonts/`, + }, + revManifest: { + dest: `${basePaths.dest}rev-manifest.json`, + }, }; - var appFiles = { - scripts: paths.scripts.src + '**/*.js', - styles: paths.styles.src + '**/*.scss', - content: paths.content.src + '**/*.yml', - pages: paths.pages.src + '**/*.jade', - layouts: paths.layouts.src + '**/*.jade', - images: paths.images.src + '**/*', - logos: paths.logos.src + '**/*', - favicons: paths.favicons.src + '**/*', - fonts: paths.fonts.src + '**/*' + const appFiles = { + scripts: `${paths.scripts.src}**/*.js`, + styles: `${paths.styles.src}**/*.scss`, + content: `${paths.content.src}**/*.yml`, + pages: `${paths.pages.src}**/*.pug`, + layouts: `${paths.layouts.src}**/*.pug`, + images: `${paths.images.src}**/*`, + logos: `${paths.logos.src}**/*`, + favicons: `${paths.favicons.src}**/*`, + fonts: `${paths.fonts.src}**/*`, }; - var components = [ - basePaths.src + 'modules/', - basePaths.src + 'partials/' + const components = [ + `${basePaths.src}modules/`, + `${basePaths.src}elements/`, + `${basePaths.src}partials/`, ]; - var gulpFiles = [ + const gulpFiles = [ 'gulp/**/*.js', - 'gulpfile.js' + 'gulpfile.js', ]; - var environments = { + const environments = { testing: { - host: argv.host, - username: argv.username, + host: argv.host, + username: argv.username, projectPath: 'preview.ginetta.net/skeleton-styleguide/', releasePath: argv.path, - privateKey: argv.privateKey - } + privateKey: argv.privateKey, + }, }; return { - root: root, - basePaths: basePaths, - languages: languages, - paths: paths, - appFiles: appFiles, - components: components, - gulpFiles: gulpFiles, - environments: environments + root, + basePaths, + languages, + paths, + appFiles, + components, + gulpFiles, + environments, + isProd: process.env.NODE_ENV === 'production', }; }; - - diff --git a/gulp/tasks/assets.js b/gulp/tasks/assets.js index d547d0d..433c1a6 100644 --- a/gulp/tasks/assets.js +++ b/gulp/tasks/assets.js @@ -1,30 +1,37 @@ -'use strict'; -var merge = require('merge-stream'); +const merge = require('merge-stream'); -module.exports = function (gulp, $, config) { - var imagesSrc = config.appFiles.images; - var imagesDest = config.paths.images.dest; - var logosSrc = config.appFiles.logos; - var logosDest = config.paths.logos.dest; - var faviconsSrc = config.appFiles.favicons; - var faviconsDest = config.paths.favicons.dest; - var fontsSrc = config.appFiles.fonts; - var fontsDest = config.paths.fonts.dest; +module.exports = (gulp, $, config) => { + const imagesSrc = config.appFiles.images; + const imagesDest = config.paths.images.dest; + const logosSrc = config.appFiles.logos; + const logosDest = config.paths.logos.dest; + const faviconsSrc = config.appFiles.favicons; + const faviconsDest = config.paths.favicons.dest; + const fontsSrc = config.appFiles.fonts; + const fontsDest = config.paths.fonts.dest; + const manifestFile = config.paths.revManifest.dest; - var task = function () { - var imagesSt = gulp.src(imagesSrc) + const task = () => { + const imagesSt = gulp.src(imagesSrc) .pipe($.changed(imagesDest)) - .pipe(gulp.dest(imagesDest)); + .pipe($.if(config.isProd, $.rev())) + .pipe($.if(config.isProd, gulp.dest(imagesDest))) + .pipe($.if(config.isProd, $.rev.manifest(manifestFile, { merge: true, base: imagesDest }))) + .pipe(gulp.dest(imagesDest)) + ; - var logosSt = gulp.src(logosSrc) + const logosSt = gulp.src(logosSrc) .pipe($.changed(logosSrc)) + .pipe($.if(config.isProd, $.rev())) + .pipe($.if(config.isProd, gulp.dest(logosSrc))) + .pipe($.if(config.isProd, $.rev.manifest(manifestFile, { merge: true, base: logosDest }))) .pipe(gulp.dest(logosDest)); - var faviconsSt = gulp.src(faviconsSrc) + const faviconsSt = gulp.src(faviconsSrc) .pipe($.changed(faviconsSrc)) .pipe(gulp.dest(faviconsDest)); - var fontsSt = gulp.src(fontsSrc) + const fontsSt = gulp.src(fontsSrc) .pipe($.changed(fontsSrc)) .pipe(gulp.dest(fontsDest)); diff --git a/gulp/tasks/clean.js b/gulp/tasks/clean.js index 6ac90a2..f44e386 100644 --- a/gulp/tasks/clean.js +++ b/gulp/tasks/clean.js @@ -1,14 +1,10 @@ -'use strict'; -var del = require('del'); +const del = require('del'); -module.exports = function (gulp, $, config) { - var destFolder = config.basePaths.dest + '*'; +module.exports = (gulp, $, config) => { + const destFolder = `${config.basePaths.dest}*`; - var task = function (cb) { - return del([destFolder]); - }; + const task = () => del([destFolder]); task.description = 'Cleans the build folder'; return task; }; - diff --git a/gulp/tasks/content.js b/gulp/tasks/content.js index 3b1244d..7823ae3 100644 --- a/gulp/tasks/content.js +++ b/gulp/tasks/content.js @@ -1,21 +1,22 @@ -'use strict'; -var merge = require('merge-stream'); -var glob = require('glob').sync; +const merge = require('merge-stream'); +const glob = require('glob').sync; -module.exports = function (gulp, $, config) { - var srcFiles = config.paths.content.src; - var languages = config.languages; - var destFiles = config.paths.content.dest; - var buildDest = config.basePaths.dest; +module.exports = (gulp, $, config) => { + const srcFiles = config.paths.content.src; + const languages = config.languages; + const destFiles = config.paths.content.dest; + const buildDest = config.basePaths.dest; // '../filename.html' => 'Filename' // Isn't there a node package to help with this? - var getFileName = function(link) { - var filename = new String(link).substring(link.lastIndexOf('/') + 1); - if(filename.lastIndexOf('.') != -1) - filename = filename.substring(0, filename.lastIndexOf('.')); - return filename; - } + const getFileName = (link) => { + // eslint-disable-next-line no-new-wrappers + let filename = new String(link).substring(link.lastIndexOf('/') + 1); + if (filename.lastIndexOf('.') !== -1) { + filename = filename.substring(0, filename.lastIndexOf('.')); + } + return filename; + }; // '../filename.html' // => @@ -23,12 +24,10 @@ module.exports = function (gulp, $, config) { // title: 'Filename', // link: '../filename.html', // } - var transformLinks = function(link) { - return { - title: getFileName(link), - link: link - } - } + const transformLinks = link => ({ + title: getFileName(link), + link + }); // '**/*.html' // => @@ -41,24 +40,22 @@ module.exports = function (gulp, $, config) { // ... // } // } - var replaceGlobs = function(key, value) { + const replaceGlobs = (key, value) => { if (key === 'links' && typeof value === 'string') { - var links = glob(value, {cwd: buildDest}); - return links.map(transformLinks); - } else { - return value; + return glob(value, { cwd: buildDest }).map(transformLinks); } - } + return value; + }; - var task = function () { + const task = () => { // Generate the language file for each language - var contentStreams = languages.map(function(language) { - return gulp.src(srcFiles + language + '/**/*.yml') - .pipe($.concat(language + '.yml')) - .pipe($.yaml({space: 2, replacer: replaceGlobs})) - // TODO: warn when there is a duplicate key - .pipe(gulp.dest(destFiles)); - }); + const contentStreams = languages.map(language => + gulp.src(`${srcFiles}${language}/**/*.yml`) + .pipe($.concat(`${language}.yml`)) + .pipe($.yaml({ space: 2, replacer: replaceGlobs })) + // TODO: warn when there is a duplicate key + .pipe(gulp.dest(destFiles)) + ); return merge(contentStreams); }; diff --git a/gulp/tasks/deploy.js b/gulp/tasks/deploy.js index 02e245d..45b8426 100644 --- a/gulp/tasks/deploy.js +++ b/gulp/tasks/deploy.js @@ -1,69 +1,60 @@ -'use strict'; -var gutil = require('gulp-util'); -var rsync = require('rsyncwrapper'); - - -module.exports = function (gulp, $, config) { - var environment = config.environments.testing; - var defaultPath = '/home/www-clients/'; - var serverPath = environment.username + '@' + environment.host; - var deploySrc = config.basePaths.dest; - var deployDest = serverPath + ':' + defaultPath + environment.projectPath + environment.releasePath; - - - var task = function (done) { - var rsyncOptions = { +const gutil = require('gulp-util'); +const rsync = require('rsyncwrapper'); + +module.exports = (gulp, $, config) => { + const environment = config.environments.testing; + const defaultPath = '/home/www-clients/'; + const serverPath = `${environment.username}@${environment.host}`; + const deploySrc = config.basePaths.dest; + const deployDest = `${serverPath}:${defaultPath}${environment.projectPath}${environment.releasePath}`; + + const task = (done) => { + const rsyncOptions = { ssh: true, src: deploySrc, dest: deployDest, recursive: true, delete: true, privateKey: environment.privateKey, - onStdout: function (data) { - console.log(data.toString('utf8')); - }, - onStderr: function (data) { - gutil.log(data.toString('utf8')); - }, - args: ['-av'] + // eslint-disable-next-line no-console + onStdout: data => console.log(data.toString('utf8')), + onStderr: data => gutil.log(data.toString('utf8')), + args: ['-av'], }; - if(!environment.username) { + if (!environment.username) { throw new gutil.PluginError({ plugin: 'Gulp deploy', message: 'You should specify a username for the deployement. ' + - 'Example: gulp deploy --path=pulls/1 --username=testuser --host=domain.com' + 'Example: gulp deploy --path=pulls/1 --username=testuser --host=domain.com', }); } - if(!environment.host) { + if (!environment.host) { throw new gutil.PluginError({ plugin: 'Gulp deploy', message: 'You should specify a host for the deployement. ' + - 'Example: gulp deploy --path=pulls/1 --username=testuser --host=domain.com' + 'Example: gulp deploy --path=pulls/1 --username=testuser --host=domain.com', }); } - if(!environment.releasePath) { + if (!environment.releasePath) { throw new gutil.PluginError({ plugin: 'Gulp deploy', message: 'You should specify a path for the deployement. ' + - 'Example: gulp deploy --path=pulls/1 --username=testuser --host=domain.com' + 'Example: gulp deploy --path=pulls/1 --username=testuser --host=domain.com', }); } - - rsync(rsyncOptions, function(error, stdout) { - gutil.log(stdout); - if(error) { - gutil.log(error); - } - done(); + rsync(rsyncOptions, (error, stdout) => { + gutil.log(stdout); + if (error) { + gutil.log(error); + } + done(); }); }; task.description = 'Deploys to testing'; return task; }; - - diff --git a/gulp/tasks/pages.js b/gulp/tasks/pages.js index 9667f0c..8c06ff6 100644 --- a/gulp/tasks/pages.js +++ b/gulp/tasks/pages.js @@ -1,80 +1,95 @@ -'use strict'; -var jade = require('jade'); -var merge = require('merge-stream'); -var path = require('path'); -var pageshelpers = require('../utils/pagesHelpers'); -var handleError = require('../utils/handleError'); - - -module.exports = function (gulp, $, config) { - var srcFiles = config.appFiles.pages; - var destFiles = config.paths.pages.dest; - var languages = config.languages; - var contentPath = config.paths.content.dest; - var baseDir = config.basePaths.src; - var moduleHelpers = pageshelpers(config); - - +const fs = require('fs'); +const yamljs = require('yamljs'); +const pugIncludeGlob = require('pug-include-glob'); +const merge = require('merge-stream'); +const path = require('path'); +const glob = require('glob'); +const _ = require('lodash'); +const pageshelpers = require('../utils/pagesHelpers'); +const handleError = require('../utils/handleError'); + +module.exports = (gulp, $, config) => { + const srcFiles = config.appFiles.pages; + const destFiles = config.paths.pages.dest; + const languages = config.languages; + const contentPath = config.paths.content.dest; + const baseDir = config.basePaths.src; + const manifestFile = config.paths.revManifest.dest; // Put the default language at the root - var getLanguagePath = function(language) { + const getLanguagePath = (language) => { if (language === config.languages[0]) { return ''; - } else { - return language + '/'; } + return `${language}/`; }; // Returns the relative path between the page and the root of the web server - var getRelativePath = function(file, language) { - var destPath = config.paths.pages.src + getLanguagePath(language); - var filePath = path.dirname(file.path); - - return (path.relative(destPath, filePath) || '.') + '/'; + const getRelativePath = (file, language) => { + const destPath = config.paths.pages.src + getLanguagePath(language); + const filePath = path.dirname(file.path); + return `${path.relative(filePath, destPath) || '.'}/`; }; - var task = function () { - + const task = () => { // Load the content for the page function loadContent(language) { - return require(contentPath + language + '.json'); + return require(`${path.resolve(__dirname, '../..')}/${contentPath}${language}.json`); } function getDestPath(language) { - var destPath = destFiles + getLanguagePath(language); + const destPath = destFiles + getLanguagePath(language); return destPath; } + function loadMergedDefinitions() { + return glob.sync(`./${config.basePaths.src}**/definition.yml`) + .reduce((acc, definitionPath) => { + const normalizedPath = definitionPath + .replace(config.basePaths.src, '') + .replace('/definition.yml', '') + ; + return _.merge(acc, { + [normalizedPath]: yamljs.load(definitionPath), + }); + }, {}) + ; + } function compilePages(language) { - var destPath = getDestPath(language); + const destPath = getDestPath(language); return gulp.src(srcFiles) - .pipe($.plumber(handleError)) - .pipe($.jadeGlobbing()) - .pipe($.data(function(file) { - return { - data: loadContent(language), - relativePath: getRelativePath(file, language), - helpers: moduleHelpers, - language: language - }; - })) - .pipe($.jade({ - jade: jade, - pretty: true, - client: false, - basedir: baseDir - })) - .pipe(gulp.dest(destPath)); + .pipe($.plumber(handleError)) + .pipe($.data((file) => { + const mergedDefinitions = loadMergedDefinitions(); + return { + data: loadContent(language), + relativePath: getRelativePath(file, language), + helpers: pageshelpers(config, mergedDefinitions), + language, + }; + })) + .pipe($.pug({ + client: false, + pretty: true, + basedir: baseDir, + plugins: [ + pugIncludeGlob(), + ], + })) + .pipe($.if(config.isProd, $.revReplace({ + manifest: fs.existsSync(manifestFile) && gulp.src([manifestFile]), + }))) + .pipe(gulp.dest(destPath)); } // Generate the pages for each language - var pagesStreams = languages.map(compilePages); + const pagesStreams = languages.map(compilePages); return merge(pagesStreams); }; - task.description = 'Generate all pages from the jade files'; + task.description = 'Generate all pages from the pug files'; return task; }; diff --git a/gulp/tasks/scripts.js b/gulp/tasks/scripts.js index 3c76490..a4b83de 100644 --- a/gulp/tasks/scripts.js +++ b/gulp/tasks/scripts.js @@ -1,49 +1,29 @@ -'use strict'; -var stream = require('../utils/browserSync').stream; -var webpack = require('webpack'); -var gulpWebpack = require('webpack-stream'); -var glob = require('glob'); +const stream = require('../utils/browserSync').stream; +const handleError = require('../utils/handleError'); +const webpack = require('webpack'); +const gulpWebpack = require('webpack-stream'); +const webpackConfig = require('../../webpack.config'); -module.exports = function (gulp, $, config) { - var tasksHelper = require('../utils/tasksHelpers')(gulp, config); - var scriptsFiles = config.appFiles.scripts; - var vendorFile = config.paths.scripts.src + 'vendor.js'; - var srcFiles = glob.sync(scriptsFiles, {ignore: vendorFile}); - var destPath = config.paths.scripts.dest; - var skeletonRoot = config.basePaths.root; - var srcRoot = config.basePaths.src; +module.exports = (gulp, $, config) => { + const scriptsFiles = config.appFiles.scripts; + const destPath = config.paths.scripts.dest; + const manifestFile = config.paths.revManifest.dest; - var task = function () { - return gulp.src(scriptsFiles) - .pipe($.eslint({envs: ['browser']})) + const task = () => + gulp.src(scriptsFiles) + .pipe($.plumber(handleError)) + .pipe($.eslint()) .pipe($.eslint.format()) - .pipe(gulpWebpack({ - debug: true, //TODO improve this one we have env depending builds - entry: { - main: srcFiles, - // Add modules you want to load from vendors to this file - vendor: vendorFile - }, - output: { - filename: 'main.js' - }, - loaders: [ - { test: /\.js$/, loader: 'babel?presets[]=es2015', exclude: /node_modules/} - ], - resolve: { - // Makes sure the paths are relative to the root and not this file - root: skeletonRoot, - // Makes sure the compiler looks for modules in /src and node_modules - modulesDirectories: [srcRoot, 'node_modules'] - }, - plugins: [ - // Makes sure the vendors are only imported once in this seperate file - new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.min.js') - ] - })) + .pipe(gulpWebpack(webpackConfig(config), webpack)) + .pipe($.if(config.isProd, $.rev())) + .pipe($.if(config.isProd, gulp.dest(destPath))) + .pipe($.if(config.isProd, $.rev.manifest(manifestFile, { + merge: true, + base: destPath, + }))) .pipe(gulp.dest(destPath)) - .pipe(stream()); - }; + .pipe(stream()) + ; task.description = 'Move all javscript files to the build'; return task; diff --git a/gulp/tasks/serve.js b/gulp/tasks/serve.js index d2d260d..e9e44b6 100644 --- a/gulp/tasks/serve.js +++ b/gulp/tasks/serve.js @@ -1,34 +1,27 @@ -'use strict'; -var browserSync = require('../utils/browserSync'); -var reload = browserSync.reload; - -var _ = require('lodash'); - -module.exports = function (gulp, $, config) { - var serverBase = config.basePaths.dest; - var scriptFiles = [config.appFiles.scripts]; - var stylesFiles = [config.appFiles.styles]; - var pagesFiles = [config.appFiles.pages, config.appFiles.layouts]; - var contentSrcFiles = config.appFiles.content; - var gulpFiles = config.gulpFiles; - var logosFiles = config.appFiles.logos; - var faviconsFiles = config.appFiles.favicons; - var imagesFiles = config.appFiles.images; - var fontsFiles = config.appFiles.fonts; - - var componentsDirs = config.components; - - _.map(componentsDirs, function(componentDir) { - stylesFiles.push(componentDir + '**/*.scss'); - }); - _.map(componentsDirs, function(componentDir) { - pagesFiles.push(componentDir + '**/*.jade'); - }); - _.map(componentsDirs, function(componentDir) { - pagesFiles.push(componentDir + '**/*.yml'); - }); - - var task = function () { +const _ = require('lodash'); +const browserSync = require('../utils/browserSync'); + +const reload = browserSync.reload; + +// eslint-disable-next-line max-statements +module.exports = (gulp, $, config) => { + const serverBase = config.basePaths.dest; + const scriptFiles = [config.appFiles.scripts]; + const stylesFiles = [config.appFiles.styles]; + const pagesFiles = [config.appFiles.pages, config.appFiles.layouts]; + const contentSrcFiles = config.appFiles.content; + const logosFiles = config.appFiles.logos; + const faviconsFiles = config.appFiles.favicons; + const imagesFiles = config.appFiles.images; + const fontsFiles = config.appFiles.fonts; + const componentsDirs = config.components; + + _.map(componentsDirs, componentDir => scriptFiles.push(`${componentDir}**/*.js`)); + _.map(componentsDirs, componentDir => stylesFiles.push(`${componentDir}**/*.scss`)); + _.map(componentsDirs, componentDir => pagesFiles.push(`${componentDir}**/*.pug`)); + _.map(componentsDirs, componentDir => pagesFiles.push(`${componentDir}**/*.yml`)); + + const task = () => { // Initialising the server browserSync.start(serverBase); diff --git a/gulp/tasks/styles.js b/gulp/tasks/styles.js index ad2dbdb..a4cf56c 100644 --- a/gulp/tasks/styles.js +++ b/gulp/tasks/styles.js @@ -1,24 +1,39 @@ -'use strict'; -var stream = require('../utils/browserSync').stream; -var handleError = require('../utils/handleError'); +const fs = require('fs'); +const stream = require('../utils/browserSync').stream; +const handleError = require('../utils/handleError'); -module.exports = function (gulp, $, config) { - var srcFiles = config.appFiles.styles; - var destFiles = config.paths.styles.dest; +module.exports = (gulp, $, config) => { + const srcFiles = config.appFiles.styles; + const destFiles = config.paths.styles.dest; + // previously rev files such as assets that might have been referenced + // in the styles (and their path needs to be updated) + const manifestFile = config.paths.revManifest.dest; - var task = function () { - return gulp.src(srcFiles) + const task = () => + gulp.src(srcFiles) .pipe($.plumber(handleError)) .pipe($.cssGlobbing({ - extensions: ['.scss'] + extensions: ['.scss'], })) - .pipe($.sourcemaps.init()) - .pipe($.sass({includePaths: ['node_modules']})) - .pipe($.autoprefixer({browsers: ['last 2 versions', 'ie 9']})) - .pipe($.sourcemaps.write({includeContent: true})) + .pipe($.if(!config.isProd, $.sourcemaps.init())) + .pipe($.sass({ + includePaths: ['node_modules'], + outputStyle: config.isProd ? 'compressed' : '', + })) + .pipe($.autoprefixer({ browsers: ['last 2 versions', 'ie 9'] })) + .pipe($.if(!config.isProd, $.sourcemaps.write({ includeContent: true }))) + .pipe($.if(config.isProd, $.revReplace({ + manifest: fs.existsSync(manifestFile) && gulp.src(manifestFile), + }))) + .pipe($.if(config.isProd, $.rev())) + .pipe($.if(config.isProd, gulp.dest(destFiles))) + .pipe($.if(config.isProd, $.rev.manifest(manifestFile, { + merge: true, + base: destFiles, + }))) .pipe(gulp.dest(destFiles)) - .pipe(stream({match: '**/*.css'})); - }; + .pipe(stream({ match: '**/*.css' })) + ; task.description = 'Generate all stylesheets from the sass files'; return task; diff --git a/gulp/tasks/tasks.js b/gulp/tasks/tasks.js index f683fe0..2d9a4b0 100644 --- a/gulp/tasks/tasks.js +++ b/gulp/tasks/tasks.js @@ -1,13 +1,11 @@ -'use strict'; +module.exports = (gulp, $, config) => { + const gulpFiles = config.gulpFiles; -module.exports = function (gulp, $, config) { - var gulpFiles = config.gulpFiles; - - var task = function () { - return gulp.src(gulpFiles) - .pipe($.eslint({envs: ['node']})) - .pipe($.eslint.format()); - }; + const task = () => + gulp.src(gulpFiles) + .pipe($.eslint()) + .pipe($.eslint.format()) + ; task.description = 'Lints the gulp tasks'; return task; diff --git a/gulp/utils/browserSync.js b/gulp/utils/browserSync.js index b2560fe..7c10292 100644 --- a/gulp/utils/browserSync.js +++ b/gulp/utils/browserSync.js @@ -1,22 +1,21 @@ -'use strict'; -var browserSync = require('browser-sync').create(); +const browserSync = require('browser-sync').create(); // This module makes sure we keep a single instance of browserSync module.exports = { - start: function(serverBase) { + start: (serverBase) => { if (browserSync.active) { browserSync.reload(); } else { browserSync.init({ server: serverBase, - index: 'index.html' + index: 'index.html', }); } }, notify: browserSync.notify, stream: browserSync.stream, - reload: function (done) { + reload: (done) => { browserSync.reload(); done(); - } + }, }; diff --git a/gulp/utils/handleError.js b/gulp/utils/handleError.js index d701d81..03fbccc 100644 --- a/gulp/utils/handleError.js +++ b/gulp/utils/handleError.js @@ -1,22 +1,17 @@ -'use strict'; - -var gNotify = require('gulp-notify'); -var bsNotify = require('./browserSync').notify; - - -module.exports = function() { - var args = Array.prototype.slice.call(arguments); +const gNotify = require('gulp-notify'); +const bsNotify = require('./browserSync').notify; +module.exports = function notify(...args) { // Send error to the terminal with gulp-notify gNotify.onError({ - title: '<%= error.plugin %>', - message: '<%= error.message %>' + title: '<%= error.plugin %>', + message: '<%= error.message %>', }).apply(this, args); // Send error to the browser with Browserify - var error = args[0]; - var browserSynMsg = 'Oh boy, there was a problem with:' + error.plugin + '
' + - 'Ckeck you terminal for more infos.'; + const error = args[0]; + const browserSynMsg = `Oh boy, there was a problem with: ${error.plugin}
` + + 'Ckeck you terminal for more infos.'; bsNotify(browserSynMsg, 6000); // Prevent gulp from hanging on this task diff --git a/gulp/utils/pagesHelpers.js b/gulp/utils/pagesHelpers.js index 87b670d..81da9dd 100644 --- a/gulp/utils/pagesHelpers.js +++ b/gulp/utils/pagesHelpers.js @@ -1,18 +1,14 @@ -'use strict'; -var yamljs = require('yamljs'); -var _ = require('lodash'); -var markdown = require('marked'); -var jadeInline = require('jade-inline-file'); - -module.exports = function (config) { - var srcDir = config.basePaths.src; +const _ = require('lodash'); +const markdown = require('marked'); +const pugInline = require('jade-inline-file'); +module.exports = (config, mergedDefinitions) => { // TODO: Rewrite and document this helper function /** * Helper doesn't validates if a user specifies a value */ - function hasValue (value) { + function hasValue(value) { return value !== null && value !== undefined; } @@ -26,7 +22,7 @@ module.exports = function (config) { * * If the user doesn't pass any value, take the default from the schema */ - function mergeSimpleOptionDefault (optionValue, optionSchema) { + function mergeSimpleOptionDefault(optionValue, optionSchema) { // if the passed options has any value for this option // just take that value if (hasValue(optionValue)) { @@ -49,20 +45,21 @@ module.exports = function (config) { * doesn't specify any value */ function mergeComplexOptionDefault(optionValue, optionSchema) { - var transformedOption = {}; + const transformedOption = {}; // For each sub-option of the schema - _.forEach(optionSchema, function(subO, subOKey) { - var subOptionValue = mergeSimpleOptionDefault(optionValue[subOKey], subO); + _.forEach(optionSchema, (subO, subOKey) => { + const subOptionValue = mergeSimpleOptionDefault(optionValue[subOKey], subO); + let realSubOKey; // process the suboption transformed key if (subOKey === 'all') { - subOKey = ''; + realSubOKey = ''; } else { - subOKey = '-' + subOKey; + realSubOKey = `-${subOKey}`; } - transformedOption[subOKey] = subOptionValue; + transformedOption[realSubOKey] = subOptionValue; }); return transformedOption; } @@ -85,12 +82,11 @@ module.exports = function (config) { // ratio: // '': value3 // border: true - var mergeDefaultOptions = function(options, path) { - var optionsSchema, schema; - options = options || {}; - schema = yamljs.load(srcDir + path + '/definition.yml'); - optionsSchema = schema.options; - return _.mapValues(optionsSchema, function(o, oKey) { + const mergeDefaultOptions = (options = {}, path) => { + const schema = mergedDefinitions[path]; + const optionsSchema = schema.options; + + return _.mapValues(optionsSchema, (o, oKey) => { // Handle simple option (options that are just an array) if (Array.isArray(o)) { return mergeSimpleOptionDefault(options[oKey], o); @@ -101,8 +97,8 @@ module.exports = function (config) { }; return { - mergeDefaultOptions: mergeDefaultOptions, - markdown: markdown, - inline: jadeInline + mergeDefaultOptions, + markdown, + inline: pugInline, }; }; diff --git a/gulp/utils/tasksHelpers.js b/gulp/utils/tasksHelpers.js index 786fc77..50b8402 100644 --- a/gulp/utils/tasksHelpers.js +++ b/gulp/utils/tasksHelpers.js @@ -1,18 +1,18 @@ -'use strict'; - function TaskHelpers(gulp, config) { - if (this instanceof TaskHelpers === false){ + if (this instanceof TaskHelpers === false) { return new TaskHelpers(gulp, config); } - this.getTask = function getTask (task) { - return require('../tasks/' + task)(this.gulp, this.$, this.config); + this.getTask = function getTask(task) { + // eslint-disable-next-line import/no-dynamic-require,global-require + return require(`../tasks/${task}`)(this.gulp, this.$, this.config); }; - this.configure = function configure (config) { - this.config = config; + this.configure = function configure(configuration) { + this.config = configuration; }; + // eslint-disable-next-line global-require this.$ = require('gulp-load-plugins')(); this.config = null; this.gulp = gulp; diff --git a/gulpfile.js b/gulpfile.js index fe367e0..8024bff 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -1,11 +1,10 @@ -'use strict'; -var gulp = require('gulp'); -var config = require('./gulp/config')(); -var t = require('./gulp/utils/tasksHelpers')(gulp, config); +const gulp = require('gulp'); +const config = require('./gulp/config')(); +const t = require('./gulp/utils/tasksHelpers')(gulp, config); -/////////////// +// ----------// // Build // -/////////////// +// ----------// // Cleans the build folder gulp.task('clean', t.getTask('clean')); @@ -16,7 +15,7 @@ gulp.task('build:assets', t.getTask('assets')); // Concatenates all the content files gulp.task('build:content', t.getTask('content')); -// Generate all pages from the jade files +// Generate all pages from the pug files gulp.task('build:pages', t.getTask('pages')); // Generate all stylesheets from the sass files @@ -29,29 +28,27 @@ gulp.task( 'build', gulp.series( 'clean', + 'build:assets', gulp.parallel( - gulp.series( - 'build:content', - 'build:pages' - ), - 'build:assets', 'build:styles', 'build:scripts' + ), + gulp.series( + 'build:content', + 'build:pages' ) ) ); - -//////////// +// -------// // Deploy // -//////////// +// -------// gulp.task('deploy', t.getTask('deploy')); - -///////////// +// ------- -// // Others // -///////////// +// ------ --// // Serve the build folder gulp.task('serve', t.getTask('serve')); diff --git a/package.json b/package.json index e5b6cab..1c83170 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "gulp": "gulp", "start": "gulp", - "build": "gulp build", + "build": "NODE_ENV=production gulp build", "test": "gulp test", "serve": "gulp serve", "deploy": "gulp deploy" @@ -18,10 +18,15 @@ "devDependencies": { "babel-core": "^6.10.4", "babel-loader": "^6.2.0", + "babel-plugin-syntax-trailing-function-commas": "^6.22.0", "babel-preset-es2015": "^6.1.18", "browser-sync": "^2.6.5", "del": "^2.2.1", - "glob": "^7.0.5", + "eslint": "^3.15.0", + "eslint-config-airbnb-base": "^11.1.0", + "eslint-config-es2015": "^1.1.0", + "eslint-plugin-import": "^2.2.0", + "glob": "^7.1.1", "gulp": "gulpjs/gulp.git#4.0", "gulp-autoprefixer": "^3.1.0", "gulp-changed": "^1.2.1", @@ -29,23 +34,27 @@ "gulp-css-globbing": "^0.1.7", "gulp-data": "^1.2.0", "gulp-eslint": "^3.0.1", - "gulp-jade": "^1.0.0", - "gulp-jade-globbing": "^0.1.9", + "gulp-if": "^2.0.2", "gulp-load-plugins": "^1.2.4", "gulp-notify": "^2.2.0", "gulp-plumber": "^1.0.0", + "gulp-pug": "^3.2.0", + "gulp-rev": "^7.1.2", + "gulp-rev-replace": "^0.4.3", "gulp-sass": "^2.0.1", "gulp-sourcemaps": "^1.5.2", "gulp-sync": "^0.1.4", "gulp-util": "^3.0.4", "gulp-yaml": "^1.0.1", - "jade": "^1.11.0", "jade-inline-file": "^0.1.0", "lodash": "^4.13.1", "marked": "^0.3.3", "merge-stream": "^1.0.0", + "pug": "^2.0.0-beta11", + "pug-include-glob": "^0.3.2", "rsyncwrapper": "^1.0.1", - "webpack": "^1.12.8", + "webpack": "^2.2.1", + "webpack-glob-entries": "^1.0.1", "webpack-stream": "^3.2.0", "yamljs": "^0.2.8", "yargs": "^4.8.0" diff --git a/src/.eslintrc b/src/.eslintrc new file mode 100644 index 0000000..7ed1003 --- /dev/null +++ b/src/.eslintrc @@ -0,0 +1,9 @@ +env: + node: false + browser: true + commonjs: true + +rules: + # override default rule. this forces trailling commas also on functions + # as we have babel transpilation that removes the syntax error. + comma-dangle: [2, "always"] diff --git a/src/layouts/default.jade b/src/layouts/default.pug similarity index 66% rename from src/layouts/default.jade rename to src/layouts/default.pug index 7cac998..7448fad 100644 --- a/src/layouts/default.jade +++ b/src/layouts/default.pug @@ -1,5 +1,3 @@ -doctype html - html(lang=language) head meta(charset='utf-8') @@ -8,7 +6,7 @@ html(lang=language) meta(name='viewport', content='width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no') meta(name='format-detection', content='telephone=no') - link(rel='stylesheet', href='#{relativePath}css/styles.css') + link(rel='stylesheet', href=relativePath + 'css/styles.css') block meta @@ -17,8 +15,6 @@ html(lang=language) body block body - script(src='#{relativePath}/js/vendor.min.js') - script(src='#{relativePath}/js/main.js') - - + script(src=relativePath + '/js/vendor.js') + script(src=relativePath + '/js/main.js') diff --git a/src/layouts/with-sidebar.jade b/src/layouts/with-sidebar.pug similarity index 65% rename from src/layouts/with-sidebar.jade rename to src/layouts/with-sidebar.pug index 93382b4..a80caaa 100644 --- a/src/layouts/with-sidebar.jade +++ b/src/layouts/with-sidebar.pug @@ -1,6 +1,6 @@ extends ../layouts/default -include ../partials/sidebar/markup.jade -include ../partials/content/markup.jade +include ../partials/sidebar/markup +include ../partials/content/markup block meta diff --git a/src/modules/colors/definition.yml b/src/modules/colors/definition.yml index a5988da..26d808c 100644 --- a/src/modules/colors/definition.yml +++ b/src/modules/colors/definition.yml @@ -1,5 +1,6 @@ data: - – name: Color Name - desc: Description - color: #00FFFF + - + name: "Color Name" + desc: "Description" + color: "#00FFFF" options: {} diff --git a/src/modules/colors/markup.jade b/src/modules/colors/markup.pug similarity index 100% rename from src/modules/colors/markup.jade rename to src/modules/colors/markup.pug diff --git a/src/modules/colors/spec.jade b/src/modules/colors/spec.pug similarity index 100% rename from src/modules/colors/spec.jade rename to src/modules/colors/spec.pug diff --git a/src/modules/component-preview/markup.jade b/src/modules/component-preview/markup.pug similarity index 100% rename from src/modules/component-preview/markup.jade rename to src/modules/component-preview/markup.pug diff --git a/src/modules/component-preview/spec.jade b/src/modules/component-preview/spec.pug similarity index 100% rename from src/modules/component-preview/spec.jade rename to src/modules/component-preview/spec.pug diff --git a/src/modules/dropdown/definition.yml b/src/modules/dropdown/definition.yml index 1699d39..025af77 100644 --- a/src/modules/dropdown/definition.yml +++ b/src/modules/dropdown/definition.yml @@ -1,10 +1,11 @@ +--- data: name: name options: - – label: Small - value: small - – label: Medium - value: medium - – label: Large - value: large + - label: Small + value: small + - label: Medium + value: medium + - label: Large + value: large options: {} diff --git a/src/modules/dropdown/markup.jade b/src/modules/dropdown/markup.pug similarity index 100% rename from src/modules/dropdown/markup.jade rename to src/modules/dropdown/markup.pug diff --git a/src/modules/dropdown/spec.jade b/src/modules/dropdown/spec.pug similarity index 100% rename from src/modules/dropdown/spec.jade rename to src/modules/dropdown/spec.pug diff --git a/src/modules/header/markup.jade b/src/modules/header/markup.pug similarity index 100% rename from src/modules/header/markup.jade rename to src/modules/header/markup.pug diff --git a/src/modules/header/spec.jade b/src/modules/header/spec.pug similarity index 100% rename from src/modules/header/spec.jade rename to src/modules/header/spec.pug diff --git a/src/modules/nav-group/definition.yml b/src/modules/nav-group/definition.yml index 0923506..1d7da7f 100644 --- a/src/modules/nav-group/definition.yml +++ b/src/modules/nav-group/definition.yml @@ -1,10 +1,11 @@ +--- data: title: list title links: - – title: Item 1 - link: # - – title: Item 2 - link: # - – title: Item 3 - link: # + - title: Item 1 + link: "#" + - title: Item 2 + link: "#" + - title: Item 3 + link: "#" options: {} diff --git a/src/modules/nav-group/markup.jade b/src/modules/nav-group/markup.pug similarity index 100% rename from src/modules/nav-group/markup.jade rename to src/modules/nav-group/markup.pug diff --git a/src/modules/nav-group/spec.jade b/src/modules/nav-group/spec.pug similarity index 100% rename from src/modules/nav-group/spec.jade rename to src/modules/nav-group/spec.pug diff --git a/src/modules/typography/markup.jade b/src/modules/typography/markup.pug similarity index 100% rename from src/modules/typography/markup.jade rename to src/modules/typography/markup.pug diff --git a/src/modules/typography/spec.jade b/src/modules/typography/spec.pug similarity index 100% rename from src/modules/typography/spec.jade rename to src/modules/typography/spec.pug diff --git a/src/pages/colors.jade b/src/pages/colors.jade deleted file mode 100644 index eb79dbc..0000000 --- a/src/pages/colors.jade +++ /dev/null @@ -1,5 +0,0 @@ -include ../**/markup.jade -extends ../layouts/default - -block body - include ../modules/colors/spec.jade diff --git a/src/pages/colors.pug b/src/pages/colors.pug new file mode 100644 index 0000000..e9bc3e8 --- /dev/null +++ b/src/pages/colors.pug @@ -0,0 +1,6 @@ +extends ../layouts/default + +include ../**/markup + +block body + include ../modules/colors/spec diff --git a/src/pages/component-preview.jade b/src/pages/component-preview.jade deleted file mode 100644 index f71ada5..0000000 --- a/src/pages/component-preview.jade +++ /dev/null @@ -1,6 +0,0 @@ -include ../**/markup.jade -extends ../layouts/default - -block body - include ../modules/component-preview/spec.jade - diff --git a/src/pages/component-preview.pug b/src/pages/component-preview.pug new file mode 100644 index 0000000..dc7d5d6 --- /dev/null +++ b/src/pages/component-preview.pug @@ -0,0 +1,6 @@ +extends ../layouts/default + +include ../**/markup + +block body + include ../modules/component-preview/spec diff --git a/src/pages/dropdown.jade b/src/pages/dropdown.jade deleted file mode 100644 index 550f24d..0000000 --- a/src/pages/dropdown.jade +++ /dev/null @@ -1,5 +0,0 @@ -include ../**/markup.jade -extends ../layouts/default - -block body - include ../modules/dropdown/spec.jade diff --git a/src/pages/dropdown.pug b/src/pages/dropdown.pug new file mode 100644 index 0000000..2bece66 --- /dev/null +++ b/src/pages/dropdown.pug @@ -0,0 +1,6 @@ +extends ../layouts/default + +include ../**/markup + +block body + include ../modules/dropdown/spec diff --git a/src/pages/header.jade b/src/pages/header.jade deleted file mode 100644 index 98d6775..0000000 --- a/src/pages/header.jade +++ /dev/null @@ -1,5 +0,0 @@ -include ../**/markup.jade -extends ../layouts/default - -block body - include ../modules/header/spec.jade diff --git a/src/pages/header.pug b/src/pages/header.pug new file mode 100644 index 0000000..20b4fbe --- /dev/null +++ b/src/pages/header.pug @@ -0,0 +1,6 @@ +extends ../layouts/default + +include ../**/markup + +block body + include ../modules/header/spec diff --git a/src/pages/index.jade b/src/pages/index.pug similarity index 100% rename from src/pages/index.jade rename to src/pages/index.pug diff --git a/src/pages/nav-group.jade b/src/pages/nav-group.jade deleted file mode 100644 index 0657540..0000000 --- a/src/pages/nav-group.jade +++ /dev/null @@ -1,5 +0,0 @@ -include ../**/markup.jade -extends ../layouts/default - -block body - include ../modules/nav-group/spec.jade diff --git a/src/pages/nav-group.pug b/src/pages/nav-group.pug new file mode 100644 index 0000000..50d0e8f --- /dev/null +++ b/src/pages/nav-group.pug @@ -0,0 +1,6 @@ +extends ../layouts/default + +include ../**/markup + +block body + include ../modules/nav-group/spec diff --git a/src/pages/typography.jade b/src/pages/typography.jade deleted file mode 100644 index 9200760..0000000 --- a/src/pages/typography.jade +++ /dev/null @@ -1,5 +0,0 @@ -include ../**/markup.jade -extends ../layouts/default - -block body - include ../modules/typography/spec.jade diff --git a/src/pages/typography.pug b/src/pages/typography.pug new file mode 100644 index 0000000..d81e179 --- /dev/null +++ b/src/pages/typography.pug @@ -0,0 +1,6 @@ +extends ../layouts/default + +include ../**/markup + +block body + include ../modules/typography/spec diff --git a/src/partials/content/markup.jade b/src/partials/content/markup.pug similarity index 100% rename from src/partials/content/markup.jade rename to src/partials/content/markup.pug diff --git a/src/partials/sidebar/markup.jade b/src/partials/sidebar/markup.pug similarity index 70% rename from src/partials/sidebar/markup.jade rename to src/partials/sidebar/markup.pug index f74ef8f..848bd63 100644 --- a/src/partials/sidebar/markup.jade +++ b/src/partials/sidebar/markup.pug @@ -1,5 +1,5 @@ -include ../../modules/header/markup.jade -include ../../modules/nav-group/markup.jade +include ../../modules/header/markup +include ../../modules/nav-group/markup mixin styleguide-sidebar(data, options) .styleguide-sidebar @@ -9,4 +9,3 @@ mixin styleguide-sidebar(data, options) each navgroup in data.navigation +styleguide-nav-group(navgroup) - diff --git a/src/partials/sidebar/spec.jade b/src/partials/sidebar/spec.pug similarity index 100% rename from src/partials/sidebar/spec.jade rename to src/partials/sidebar/spec.pug diff --git a/src/scripts/main.js b/src/scripts/main.js index 5b589a1..ea3de42 100644 --- a/src/scripts/main.js +++ b/src/scripts/main.js @@ -1,37 +1,17 @@ -'use strict'; - // This is how you require a component from node_modules // Make sure to add it to the vendors in /src/scripts/vendor.js -var $ = require('jquery'); -var contentIframeEl = $('#styleguide-content'); -var navItems = $('.js-styleguide-nav-item'); -var activeClass = 'styleguide-nav-item--active'; -var sidebar = $('.styleguide-sidebar'); - -// load the correct page in the iframe -window.onload = function() { - loadIframe(); -}; -// Event handler for the browsers back/forward buttons -window.addEventListener('popstate', function(event) { - loadIframe(); -}); +// This is how you require a component from node_modules +// Make sure to add it to the vendors in /src/scripts/vendor.js +const $ = require('jquery'); -// The code for the website comes here. -navItems.each(function(i) { - $(this).find('.js-styleguide-nav-link').on('click', function(e) { - var target = $(this).attr('href'); - e.preventDefault(); - setIframeSrc(target); - window.history.pushState(null, null, '?page=' + target); - $('.' + activeClass).removeClass(activeClass); - $(this).parent().addClass(activeClass); - }); -}) +const contentIframeEl = $('#styleguide-content'); +const navItems = $('.js-styleguide-nav-item'); +const activeClass = 'styleguide-nav-item--active'; +const sidebar = $('.styleguide-sidebar'); function setIframeSrc(url) { - var parentContainer = contentIframeEl.parent(); + const parentContainer = contentIframeEl.parent(); contentIframeEl.remove(); contentIframeEl.attr('src', url); parentContainer.append(contentIframeEl); @@ -41,14 +21,22 @@ function setIframeSrc(url) { } function convertURL(url) { - var page = url.substr(url.indexOf('?') + 6); - var baseURL = window.location.href.split('?')[0]; + const page = url.substr(url.indexOf('?') + 6); + const baseURL = window.location.href.split('?')[0]; return baseURL + page; } +function setActiveClass(url) { + sidebar.find(`.${activeClass}`).removeClass(activeClass); + if (url.includes('?page=')) { + const target = url.substr(url.indexOf('?') + 6).split('.')[0]; + $(`a[href*=${target}]`).addClass(activeClass); + } +} + function loadIframe() { - var currentURL = window.location.href; - var url = convertURL(window.location.href); + const currentURL = window.location.href; + const url = convertURL(window.location.href); setActiveClass(currentURL); if (currentURL.includes('?page=')) { setIframeSrc(url); @@ -57,10 +45,20 @@ function loadIframe() { } } -function setActiveClass(url) { - sidebar.find('.' + activeClass).removeClass(activeClass); - if (url.includes('?page=')) { - var target = url.substr(url.indexOf('?') + 6).split('.')[0]; - $('a[href*=' + target + ']').addClass(activeClass); - } -} +// load the correct page in the iframe +window.onload = () => loadIframe(); + +// Event handler for the browsers back/forward buttons +window.addEventListener('popstate', loadIframe); + +// The code for the website comes here. +navItems.each(function () { + $(this).find('.js-styleguide-nav-link').on('click', function (e) { + const target = $(this).attr('href'); + e.preventDefault(); + setIframeSrc(target); + window.history.pushState(null, null, `?page=${target}`); + $(`.${activeClass}`).removeClass(activeClass); + $(this).parent().addClass(activeClass); + }); +}); diff --git a/src/scripts/vendor.js b/src/scripts/vendor.js index 825ae52..4318bd2 100644 --- a/src/scripts/vendor.js +++ b/src/scripts/vendor.js @@ -1,4 +1,2 @@ -'use strict'; - // Require here all the files that you want to be bundled in the vendor.js file require('jquery'); diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..9bacb1d --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,81 @@ +const webpack = require('webpack'); +const path = require('path'); +const globEntries = require('webpack-glob-entries'); + +module.exports = config => ({ + // Here the application starts executing + // and webpack starts bundling + // can be string | object {entryname: entrypath} | array + // we are using an object here (result of `globEntries`) + entry: globEntries(config.appFiles.scripts), + + // options related to how webpack emits results + output: { + // the filename template for entry chunks + filename: '[name].js', + + // the target directory for all output files + // must be an absolute path (thus the `path.resolve`) + path: path.resolve(__dirname, 'build'), + }, + + module: { + rules: [ + { + test: /\.js$/, + exclude: /node_modules/, + use: ['babel-loader'], + }, + ], + }, + + // options for resolving module requests + resolve: { + + // directories where to look for modules + modules: [ + 'node_modules', + path.join(__dirname, '.'), + path.resolve(__dirname, 'src'), + ], + }, + + plugins: [ + // The CommonsChunkPlugin is an opt-in feature that creates a separate file + // (known as a chunk), consisting of common modules shared between multiple + // entry points. By separating common modules from bundles, the resulting + // chunked file can be loaded once initially, and stored in cache for later + // use. This results in pagespeed optimizations as the browser can quickly + // serve the shared code from cache, rather than being forced to load a + // larger bundle whenever a new page is visited. + new webpack.optimize.CommonsChunkPlugin({ + name: 'vendor', + filename: 'vendor.js', + }), + + // Production-Only Plugins + // (they get concatenated only if we're building for production) + // See: https://webpack.js.org/guides/production-build/#the-manual-way-configuring-webpack-for-multiple-environments + ].concat(config.isProd ? [ + new webpack.LoaderOptionsPlugin({ + minimize: true, + debug: false, + }), + new webpack.DefinePlugin({ + 'process.env': { + NODE_ENV: JSON.stringify('production'), + }, + }), + new webpack.optimize.UglifyJsPlugin({ + beautify: false, + mangle: { + screw_ie8: true, + keep_fnames: true, + }, + compress: { + screw_ie8: true, + }, + comments: false, + }), + ] : []), +}); diff --git a/wercker.yml b/wercker.yml new file mode 100644 index 0000000..eeb5a8e --- /dev/null +++ b/wercker.yml @@ -0,0 +1,54 @@ +box: node + +build: + steps: + + - script: + name: echo nodejs information + code: | + echo "node version $(node -v) running" + echo "npm version $(npm -v) running" + - npm-install + + - maxon/npm-run: + script: build + +deploy-branch: + steps: + - install-packages: + packages: rsync + + - add-to-known_hosts: + hostname: $G_STAGING_HOST + + - add-ssh-key: + keyname: G_STAGING_KEY + + - lejoe/rsync-deploy: + host: $G_STAGING_HOST + homepath: $G_STAGING_HOME_PATH + directory: $G_STAGING_PROJECT_PATH/branch/$WERCKER_GIT_BRANCH + user: $G_STAGING_USER + sshkey: $G_STAGING_KEY + source: $WERCKER_SOURCE_DIR/build/ + +deploy-master: + steps: + - install-packages: + packages: rsync + + - add-to-known_hosts: + hostname: $G_STAGING_HOST + + - add-ssh-key: + keyname: G_STAGING_KEY + + - lejoe/rsync-deploy: + host: $G_STAGING_HOST + homepath: $G_STAGING_HOME_PATH + directory: $G_STAGING_PROJECT_PATH/master + user: $G_STAGING_USER + sshkey: $G_STAGING_KEY + source: $WERCKER_SOURCE_DIR/build/ + sshkey: $G_LIVE_KEY + source: $WERCKER_SOURCE_DIR/build/