From f6bdc7b48cfaeef4a387825b972004574a0b19d8 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Sun, 4 Sep 2016 19:13:16 -0700 Subject: [PATCH] Refactor build routine and switch to airbnb style (#1703) - Relocate webpack stuff to assets/build - Switch all js to airbnb code style - Update webpack to v2.0 (beta) - Update all other dependencies - Assets manifest uses relative path as key [1] - Code should be compatible with Node 4.5.0 - All dependencies have been updated [1]: Previously the assets manifest would use the basename of a file path as its key when looking up a cachebusted file. This was to be consistent with Sage 8. This change makes it so that the relative path is used instead. To clarify, review the following example. Before: ``` { "main.js": "scripts/main_5f4bfc9a9f82291c6dea.js", "main.css": "styles/main_5f4bfc9a9f82291c6dea.css", "customizer.js": "scripts/customizer_5f4bfc9a9f82291c6dea.js" } ``` After: ``` { "scripts/main.js":"scripts/main_5f4bfc9a9f82291c6dea.js", "styles/main.css":"styles/main_5f4bfc9a9f82291c6dea.css", "scripts/customizer.js":"scripts/customizer_5f4bfc9a9f82291c6dea.js" } ``` --- .eslintrc | 11 +- .travis.yml | 9 +- assets/build/.eslintrc | 8 + assets/build/config.js | 52 +++++ assets/build/public-path.js | 8 + assets/build/util/mergeWithConcat.js | 14 ++ assets/build/webpack.config.js | 200 +++++++++++++++++ assets/build/webpack.config.production.js | 40 ++++ assets/build/webpack.config.watch.js | 22 ++ assets/config.json | 5 +- assets/scripts/customizer.js | 2 +- assets/scripts/main.js | 10 +- assets/scripts/routes/About.js | 2 +- assets/scripts/routes/Common.js | 2 +- assets/scripts/routes/Home.js | 2 +- assets/scripts/util/camelCase.js | 5 + assets/scripts/util/public-path.js | 8 - assets/scripts/util/router.js | 15 +- package.json | 76 ++++--- src/lib/Sage/Asset.php | 5 +- watch.js | 33 --- webpack.config.js | 248 ---------------------- 22 files changed, 426 insertions(+), 351 deletions(-) create mode 100644 assets/build/.eslintrc create mode 100644 assets/build/config.js create mode 100644 assets/build/public-path.js create mode 100644 assets/build/util/mergeWithConcat.js create mode 100644 assets/build/webpack.config.js create mode 100644 assets/build/webpack.config.production.js create mode 100644 assets/build/webpack.config.watch.js create mode 100644 assets/scripts/util/camelCase.js delete mode 100644 assets/scripts/util/public-path.js delete mode 100644 watch.js delete mode 100644 webpack.config.js diff --git a/.eslintrc b/.eslintrc index 56260bd..960cdd9 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,17 +1,14 @@ { "root": true, - "extends": "eslint:recommended", + "extends": "airbnb", "globals": { "wp": true }, "env": { + "amd": true, "browser": true, "jquery": true, - "node": true, - "amd": true + "node": true }, - "parser": "babel-eslint", - "rules": { - "no-console": 0 - } + "parser": "babel-eslint" } diff --git a/.travis.yml b/.travis.yml index d992245..4bc8d16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,8 +7,8 @@ php: - nightly env: - - TRAVIS_NODE_VERSION="4.2" CXX="g++-4.8" - - TRAVIS_NODE_VERSION="5.3" CXX="g++-4.8" + - TRAVIS_NODE_VERSION="4" CXX="g++-4.8" + - TRAVIS_NODE_VERSION="6" CXX="g++-4.8" matrix: fast_finish: true @@ -33,7 +33,7 @@ before_install: - composer self-update install: - - source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION + - source ~/.nvm/nvm.sh && nvm install $TRAVIS_NODE_VERSION && nvm use $TRAVIS_NODE_VERSION - travis_retry npm install -g npm@latest - travis_retry npm install -g eslint - node -v && npm -v @@ -43,5 +43,8 @@ install: - composer install -o --prefer-dist --no-interaction script: + - npm run test - npm run build + - npm run clean + - npm run "build:production" - composer test diff --git a/assets/build/.eslintrc b/assets/build/.eslintrc new file mode 100644 index 0000000..60f6bb7 --- /dev/null +++ b/assets/build/.eslintrc @@ -0,0 +1,8 @@ +{ + "root": false, + "extends": "airbnb", + "rules": { + "import/no-extraneous-dependencies": 0, + "prefer-rest-params": 0 + } +} diff --git a/assets/build/config.js b/assets/build/config.js new file mode 100644 index 0000000..f798163 --- /dev/null +++ b/assets/build/config.js @@ -0,0 +1,52 @@ +/* eslint-disable import/no-extraneous-dependencies */ + +const path = require('path'); +const argv = require('minimist')(process.argv.slice(2)); +const glob = require('glob-all'); +const merge = require('lodash/merge'); + +const mergeWithConcat = require('./util/mergeWithConcat'); +const userConfig = require('../config'); + +const isProduction = !!((argv.env && argv.env.production) || argv.p); +const rootPath = (userConfig.paths && userConfig.paths.root) + ? userConfig.paths.root + : process.cwd(); + +const config = mergeWithConcat({ + copy: ['images/**/*'], + proxyUrl: 'http://localhost:3000', + cacheBusting: '[name]_[hash]', + paths: { + root: rootPath, + assets: path.join(rootPath, 'assets'), + dist: path.join(rootPath, 'dist'), + }, + enabled: { + sourceMaps: !isProduction, + minify: isProduction, + cacheBusting: isProduction, + watcher: !!argv.watch, + uglifyJs: !(argv.p || argv.optimizeMinimize), + }, + watch: [ + 'templates/**/*.php', + 'src/**/*.php', + ], +}, userConfig); + +Object.keys(config.entry).forEach(id => + config.entry[id].unshift(path.join(__dirname, 'public-path.js'))); + +module.exports = mergeWithConcat(config, { + env: merge({ production: isProduction, development: !isProduction }, argv.env), + entry: { + get files() { + return glob.sync(config.copy, { + cwd: config.paths.assets, + mark: true, + }).filter(file => !((file.slice(-1) === '/') || (!file.indexOf('*') === -1))) + .map(file => path.join(config.paths.assets, file)); + }, + }, +}); diff --git a/assets/build/public-path.js b/assets/build/public-path.js new file mode 100644 index 0000000..f92bee6 --- /dev/null +++ b/assets/build/public-path.js @@ -0,0 +1,8 @@ +/* eslint-env browser */ +/* globals WEBPACK_PUBLIC_PATH */ + +// Dynamically set absolute public path from current protocol and host +if (WEBPACK_PUBLIC_PATH) { + // eslint-disable-next-line no-undef, camelcase + __webpack_public_path__ = `${location.protocol}//${location.host}${WEBPACK_PUBLIC_PATH}`; +} diff --git a/assets/build/util/mergeWithConcat.js b/assets/build/util/mergeWithConcat.js new file mode 100644 index 0000000..316f72a --- /dev/null +++ b/assets/build/util/mergeWithConcat.js @@ -0,0 +1,14 @@ +/* eslint-disable import/no-extraneous-dependencies */ + +const mergeWith = require('lodash/mergeWith'); + +module.exports = function mergeWithConcat() { + const args = [].slice.call(arguments); + args.push((a, b) => { + if (Array.isArray(a) && Array.isArray(b)) { + return a.concat(b); + } + return undefined; + }); + return mergeWith.apply(this, args); +}; diff --git a/assets/build/webpack.config.js b/assets/build/webpack.config.js new file mode 100644 index 0000000..c1b431e --- /dev/null +++ b/assets/build/webpack.config.js @@ -0,0 +1,200 @@ +/* eslint-disable import/no-extraneous-dependencies */ +const webpack = require('webpack'); +const path = require('path'); +const qs = require('qs'); +const autoprefixer = require('autoprefixer'); +const CleanPlugin = require('clean-webpack-plugin'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); +const ImageminPlugin = require('imagemin-webpack-plugin').default; +const imageminMozjpeg = require('imagemin-mozjpeg'); + +const mergeWithConcat = require('./util/mergeWithConcat'); +const webpackConfigProduction = require('./webpack.config.production'); +const webpackConfigWatch = require('./webpack.config.watch'); +const config = require('./config'); + +const publicPath = `${config.publicPath}/${path.basename(config.paths.dist)}/`; +const assetsFilenames = (config.enabled.cacheBusting) ? config.cacheBusting : '[name]'; +const sourceMapQueryStr = (config.enabled.sourceMaps) ? '+sourceMap' : '-sourceMap'; + +const jsLoader = { + test: /\.js$/, + exclude: [/(node_modules|bower_components)(?![/|\\](bootstrap|foundation-sites))/], + loaders: [`babel?presets[]=${path.resolve('./node_modules/babel-preset-es2015')}&cacheDirectory`], +}; + +if (config.enabled.watcher) { + jsLoader.loaders.unshift('monkey-hot'); +} + +const webpackConfig = { + context: config.paths.assets, + entry: config.entry, + devtool: (config.enabled.sourceMaps ? '#source-map' : undefined), + output: { + path: config.paths.dist, + publicPath, + filename: `scripts/${assetsFilenames}.js`, + }, + module: { + preLoaders: [ + { + test: /\.js?$/, + include: config.paths.assets, + loader: 'eslint', + }, + ], + loaders: [ + jsLoader, + { + test: /\.css$/, + include: config.paths.assets, + loader: ExtractTextPlugin.extract({ + fallbackLoader: 'style', + loader: [ + `css?${sourceMapQueryStr}`, + 'postcss', + ], + }), + }, + { + test: /\.scss$/, + include: config.paths.assets, + loader: ExtractTextPlugin.extract({ + fallbackLoader: 'style', + loader: [ + `css?${sourceMapQueryStr}`, + 'postcss', + `resolve-url?${sourceMapQueryStr}`, + `sass?${sourceMapQueryStr}`, + ], + }), + }, + { + test: /\.(png|jpe?g|gif|svg)$/, + include: config.paths.assets, + loaders: [ + `file?${qs.stringify({ + name: '[path][name].[ext]', + })}`, + ], + }, + { + test: /\.(ttf|eot)$/, + include: config.paths.assets, + loader: `file?${qs.stringify({ + name: `[path]${assetsFilenames}.[ext]`, + })}`, + }, + { + test: /\.woff2?$/, + include: config.paths.assets, + loader: `url?${qs.stringify({ + limit: 10000, + mimetype: 'application/font-woff', + name: `[path]${assetsFilenames}.[ext]`, + })}`, + }, + { + test: /\.(ttf|eot|woff2?|png|jpe?g|gif|svg)$/, + include: /node_modules|bower_components/, + loader: 'file', + query: { + name: `vendor/${config.cacheBusting}.[ext]`, + }, + }, + ], + }, + modules: [ + config.paths.assets, + 'node_modules', + 'bower_components', + ], + enforceExtensions: false, + externals: { + jquery: 'jQuery', + }, + plugins: [ + new CleanPlugin([config.paths.dist], config.paths.root), + new ImageminPlugin({ + optipng: { + optimizationLevel: 7, + }, + gifsicle: { + optimizationLevel: 3, + }, + pngquant: { + quality: '65-90', + speed: 4, + }, + svgo: { + removeUnknownsAndDefaults: false, + cleanupIDs: false, + }, + jpegtran: null, + plugins: [imageminMozjpeg({ + quality: 75, + })], + disable: (config.enabled.watcher), + }), + new ExtractTextPlugin({ + filename: `styles/${assetsFilenames}.css`, + allChunks: true, + disable: (config.enabled.watcher), + }), + new webpack.ProvidePlugin({ + $: 'jquery', + jQuery: 'jquery', + 'window.jQuery': 'jquery', + Tether: 'tether', + 'window.Tether': 'tether', + }), + new webpack.DefinePlugin({ + WEBPACK_PUBLIC_PATH: (config.enabled.watcher) + ? JSON.stringify(publicPath) + : false, + }), + new webpack.LoaderOptionsPlugin({ + minimize: config.enabled.minify, + debug: config.enabled.watcher, + stats: { colors: true }, + postcss: [ + autoprefixer({ + browsers: [ + 'last 2 versions', + 'android 4', + 'opera 12', + ], + }), + ], + eslint: { + failOnWarning: false, + failOnError: true, + }, + }), + ], +}; + +module.exports = webpackConfig; + +if (config.env.production) { + module.exports = mergeWithConcat(webpackConfig, webpackConfigProduction); +} + +if (config.enabled.watcher) { + module.exports = mergeWithConcat(webpackConfig, webpackConfigWatch); +} + +if (config.enabled.uglifyJs) { + module.exports.plugins.push( + new webpack.optimize.UglifyJsPlugin({ + compress: config.enabled.minify ? { + drop_debugger: true, + dead_code: true, + warnings: false, + } : false, + sourceMap: config.enabled.sourceMaps, + output: { comments: false }, + }) + ); +} diff --git a/assets/build/webpack.config.production.js b/assets/build/webpack.config.production.js new file mode 100644 index 0000000..45b6802 --- /dev/null +++ b/assets/build/webpack.config.production.js @@ -0,0 +1,40 @@ +/* eslint-disable import/no-extraneous-dependencies */ +const AssetsPlugin = require('assets-webpack-plugin'); +const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); +const cssnano = require('cssnano'); +const path = require('path'); + +const config = require('./config'); + +/** + * Process AssetsPlugin output and format it + * for Sage: {"[name].[ext]":"[name]_[hash].[ext]"} + * @param {Object} assets passed by processOutput + * @return {String} JSON + */ +const assetsPluginProcessOutput = (assets) => { + const results = {}; + Object.keys(assets).forEach(name => { + Object.keys(assets[name]).forEach(ext => { + const filename = `${path.dirname(assets[name][ext])}/${path.basename(`${name}.${ext}`)}`; + results[filename] = assets[name][ext]; + }); + }); + return JSON.stringify(results); +}; + +module.exports = { + plugins: [ + new AssetsPlugin({ + path: config.paths.dist, + filename: 'assets.json', + fullPath: false, + processOutput: assetsPluginProcessOutput, + }), + new OptimizeCssAssetsPlugin({ + cssProcessor: cssnano, + cssProcessorOptions: { discardComments: { removeAll: true } }, + canPrint: true, + }), + ], +}; diff --git a/assets/build/webpack.config.watch.js b/assets/build/webpack.config.watch.js new file mode 100644 index 0000000..2d1ca65 --- /dev/null +++ b/assets/build/webpack.config.watch.js @@ -0,0 +1,22 @@ +/* eslint-disable import/no-extraneous-dependencies */ +const BrowserSyncPlugin = require('browser-sync-webpack-plugin'); +const url = require('url'); + +const config = require('./config'); + +module.exports = { + output: { pathinfo: true }, + debug: true, + devTool: 'cheap-module-source-map', + plugins: [ + new BrowserSyncPlugin({ + host: url.parse(config.proxyUrl).hostname, + port: url.parse(config.proxyUrl).port, + proxy: config.devUrl, + files: [ + 'templates/**/*.php', + 'src/**/*.php', + ], + }), + ], +}; diff --git a/assets/config.json b/assets/config.json index a6edc97..2cbec61 100644 --- a/assets/config.json +++ b/assets/config.json @@ -1,7 +1,6 @@ { "entry": { "main": [ - "./scripts/util/public-path.js", "./scripts/main.js", "./styles/main.scss" ], @@ -10,5 +9,7 @@ ] }, "publicPath": "/app/themes/sage", - "devUrl": "http://example.dev" + "devUrl": "https://example.dev", + "proxyUrl": "https://localhost:3000", + "cacheBusting": "[name]_[hash:8]" } diff --git a/assets/scripts/customizer.js b/assets/scripts/customizer.js index 5f97349..c5f5021 100644 --- a/assets/scripts/customizer.js +++ b/assets/scripts/customizer.js @@ -1,5 +1,5 @@ import $ from 'jquery'; wp.customize('blogname', (value) => { - value.bind((to) => $('.brand').text(to)) + value.bind((to) => $('.brand').text(to)); }); diff --git a/assets/scripts/main.js b/assets/scripts/main.js index 48e9a3f..4730de1 100644 --- a/assets/scripts/main.js +++ b/assets/scripts/main.js @@ -1,12 +1,12 @@ // import external dependencies -import 'jquery' -import 'bootstrap/dist/js/bootstrap' +import 'jquery'; +import 'bootstrap/dist/js/bootstrap'; // import local dependencies import Router from './util/router'; import common from './routes/Common'; import home from './routes/Home'; -import about_us from './routes/About'; +import aboutUs from './routes/About'; // Use this variable to set up the common and page specific functions. If you // rename this variable, you will also need to rename the namespace below. @@ -15,8 +15,8 @@ const routes = { common, // Home page home, - // About us page, note the change from about-us to about_us. - about_us + // About us page, note the change from about-us to aboutUs. + aboutUs, }; // Load Events diff --git a/assets/scripts/routes/About.js b/assets/scripts/routes/About.js index d9ab68a..fae4c82 100644 --- a/assets/scripts/routes/About.js +++ b/assets/scripts/routes/About.js @@ -1,5 +1,5 @@ export default { init() { // JavaScript to be fired on the about us page - } + }, }; diff --git a/assets/scripts/routes/Common.js b/assets/scripts/routes/Common.js index bc13db8..3acfc95 100644 --- a/assets/scripts/routes/Common.js +++ b/assets/scripts/routes/Common.js @@ -4,5 +4,5 @@ export default { }, finalize() { // JavaScript to be fired on all pages, after page specific JS is fired - } + }, }; diff --git a/assets/scripts/routes/Home.js b/assets/scripts/routes/Home.js index 766017b..c37d80b 100644 --- a/assets/scripts/routes/Home.js +++ b/assets/scripts/routes/Home.js @@ -4,5 +4,5 @@ export default { }, finalize() { // JavaScript to be fired on the home page, after the init JS - } + }, }; diff --git a/assets/scripts/util/camelCase.js b/assets/scripts/util/camelCase.js new file mode 100644 index 0000000..c0b741d --- /dev/null +++ b/assets/scripts/util/camelCase.js @@ -0,0 +1,5 @@ +// the most terrible camelizer on the internet, guaranteed! +export default (str) => `${str.charAt(0).toLowerCase()}${str.replace(/[\W_]/g, '|').split('|') + .map(part => `${part.charAt(0).toUpperCase()}${part.slice(1)}`) + .join('') + .slice(1)}`; diff --git a/assets/scripts/util/public-path.js b/assets/scripts/util/public-path.js deleted file mode 100644 index af588c2..0000000 --- a/assets/scripts/util/public-path.js +++ /dev/null @@ -1,8 +0,0 @@ -/* globals WEBPACK_PUBLIC_PATH */ - -// Dynamically set absolute public path from current protocol and host -if (WEBPACK_PUBLIC_PATH !== false) { - /* eslint-disable no-undef */ - __webpack_public_path__ = location.protocol + '//' + location.host + WEBPACK_PUBLIC_PATH; - /*eslint-enable no-undef*/ -} diff --git a/assets/scripts/util/router.js b/assets/scripts/util/router.js index bfb444c..82798fb 100644 --- a/assets/scripts/util/router.js +++ b/assets/scripts/util/router.js @@ -6,6 +6,8 @@ * replace the dash with an underscore when adding it to the object below. * ======================================================================== */ +import camelCase from './camelCase'; + // The routing fires all common scripts, followed by the page specific scripts. // Add additional events for more control over timing e.g. a finalize event export default class Router { @@ -25,10 +27,15 @@ export default class Router { this.fire('common'); // Fire page-specific init JS, and then finalize JS - document.body.className.replace(/-/g, '_').split(/\s+/).forEach((className) => { - this.fire(className); - this.fire(className, 'finalize'); - }); + document.body.className + .toLowerCase() + .replace(/-/g, '_') + .split(/\s+/) + .map(camelCase) + .forEach((className) => { + this.fire(className); + this.fire(className, 'finalize'); + }); // Fire common finalize JS this.fire('common', 'finalize'); diff --git a/package.json b/package.json index 56435dc..39a4a40 100644 --- a/package.json +++ b/package.json @@ -18,55 +18,63 @@ } ], "scripts": { - "build:production": "webpack -p --progress --release", - "build": "webpack -d --progress", - "watch": "node watch.js --watch", - "lint": "eslint -c .eslintrc assets/scripts watch.js webpack.config.js" + "build": "webpack --progress --config assets/build/webpack.config.js", + "build:production": "npm run build -s -- -p", + "start": "npm run build -s -- --watch", + "clean": "node node_modules/rimraf/bin.js dist", + "lint": "node node_modules/eslint/bin/eslint.js assets/scripts assets/build", + "test": "npm run lint -s" }, "engines": { - "node": ">=4" + "node": ">=5" }, "devDependencies": { "assets-webpack-plugin": "^3.4.0", - "autoprefixer": "^6.1.0", - "babel-cli": "^6.6.5", - "babel-core": "^6.7.4", - "babel-eslint": "^6.0.0", - "babel-loader": "^6.2.4", - "babel-preset-es2015": "^6.13.2", - "babel-register": "^6.5.2", - "babel-runtime": "^6.5.0", - "body-parser": "^1.14.1", - "browser-sync": "^2.11.2", - "clean-webpack-plugin": "^0.1.8", - "css-loader": "^0.23.1", - "cssnano": "^3.5.2", - "eslint": "^3.2.2", - "eslint-loader": "^1.3.0", - "eslint-plugin-react": "^6.0.0", - "extract-text-webpack-plugin": "^1.0.1", + "autoprefixer": "^6.4.0", + "babel-cli": "^6.14.0", + "babel-core": "^6.14.0", + "babel-eslint": "^6.1.2", + "babel-loader": "^6.2.5", + "babel-preset-es2015-webpack": "^6.4.3", + "babel-register": "^6.14.0", + "babel-runtime": "^6.11.6", + "body-parser": "^1.15.2", + "browser-sync": "^2.14.0", + "browser-sync-webpack-plugin": "^1.1.2", + "clean-webpack-plugin": "^0.1.10", + "css-loader": "^0.24.0", + "cssnano": "^3.7.4", + "eslint": "^3.4.0", + "eslint-config-airbnb": "^10.0.1", + "eslint-config-airbnb-es5": "^1.0.9", + "eslint-loader": "^1.5.0", + "eslint-plugin-import": "^1.14.0", + "eslint-plugin-jsx-a11y": "^2.2.0", + "eslint-plugin-react": "^6.2.0", + "extract-text-webpack-plugin": "^2.0.0-beta.3", "file-loader": "^0.9.0", - "image-webpack-loader": "^2.0.0", - "imagemin-pngcrush": "^5.0.0", + "glob-all": "^3.1.0", + "imagemin-mozjpeg": "^6.0.0", + "imagemin-webpack-plugin": "^1.0.8", "imports-loader": "^0.6.5", + "lodash": "^4.15.0", "minimist": "^1.2.0", "monkey-hot-loader": "0.0.3", - "node-sass": "^3.4.2", + "node-sass": "^3.8.0", "optimize-css-assets-webpack-plugin": "^1.3.0", - "postcss": "^5.0.18", - "postcss-loader": "^0.9.1", - "qs": "^6.1.0", - "resolve-url-loader": "^1.4.3", + "postcss": "^5.1.2", + "postcss-loader": "^0.11.0", + "qs": "^6.2.1", + "resolve-url-loader": "^1.6.0", + "rimraf": "^2.5.4", "sass-loader": "^4.0.0", - "style-loader": "^0.13.0", + "style-loader": "^0.13.1", "url-loader": "^0.5.7", - "webpack": "^1.12.14", - "webpack-dev-middleware": "^1.6", - "webpack-hot-middleware": "^2.10.0" + "webpack": "^2.1.0-beta.21" }, "dependencies": { "bootstrap": "github:twbs/bootstrap#v4-dev", "font-awesome": "^4.6.3", - "jquery": "^1.12.4" + "jquery": "1.12.4 - 3" } } diff --git a/src/lib/Sage/Asset.php b/src/lib/Sage/Asset.php index 143fd7e..b013820 100644 --- a/src/lib/Sage/Asset.php +++ b/src/lib/Sage/Asset.php @@ -21,8 +21,7 @@ class Asset public function __construct($file, ManifestInterface $manifest = null) { $this->manifest = $manifest; - $this->asset = basename($file); - $this->dir = dirname($file) != '.' ? dirname($file) : ''; + $this->asset = $file; } public function __toString() @@ -33,6 +32,6 @@ class Asset public function getUri() { $file = ($this->manifest ? $this->manifest->get($this->asset) : $this->asset); - return get_template_directory_uri() . self::$dist . '/' . $this->dir . '/' . $file; + return get_template_directory_uri() . self::$dist . "/$file"; } } diff --git a/watch.js b/watch.js deleted file mode 100644 index 0a867bf..0000000 --- a/watch.js +++ /dev/null @@ -1,33 +0,0 @@ -// External dependencies -var webpack = require('webpack'), - webpackDevMiddleware = require('webpack-dev-middleware'), - webpackHotMiddleware = require('webpack-hot-middleware'), - browserSync = require('browser-sync'); - -// Internal dependencies -var webpackConfig = require('./webpack.config'), - config = require('./assets/config'); - -// Internal variables -var compiler = webpack(webpackConfig); - -browserSync.init({ - proxy: { - target: config.devUrl, - middleware: [ - webpackDevMiddleware(compiler, { - publicPath: webpackConfig.output.publicPath, - stats: { - colors: true - } - }), - webpackHotMiddleware(compiler, { - log: browserSync.notify - }) - ] - }, - files: [ - 'templates/**/*.php', - 'src/**/*.php' - ] -}); diff --git a/webpack.config.js b/webpack.config.js deleted file mode 100644 index ba5de4e..0000000 --- a/webpack.config.js +++ /dev/null @@ -1,248 +0,0 @@ -// External dependencies -var webpack = require('webpack'), - path = require('path'), - argv = require('minimist')(process.argv.slice(2)), - qs = require('qs'), - autoprefixer = require('autoprefixer'), - Clean = require("clean-webpack-plugin"), - AssetsPlugin = require('assets-webpack-plugin'), - ExtractTextPlugin = require('extract-text-webpack-plugin'), - OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'), - cssnano = require('cssnano'); - -// Internal dependencies -var config = require('./assets/config'); - -// Internal variables -var scriptsFilename = (argv.release) ? 'scripts/[name]_[hash].js' : 'scripts/[name].js', - stylesFilename = (argv.release) ? 'styles/[name]_[hash].css' : 'styles/[name].css', - sourceMapQueryStr = (argv.release) ? '-sourceMap' : '+sourceMap', - assets = 'assets/', - dist = 'dist/', - jsLoader, - webpackConfig; - -jsLoader = { - test: /\.js$/, - exclude: [ /(node_modules|bower_components)(?![/|\\](bootstrap|foundation-sites))/ ], - loaders: [ 'babel?presets[]='+path.resolve('./node_modules/babel-preset-es2015')+'&cacheDirectory' ] -}; - -if (argv.watch) { // '--watch' to add monkey-hot - jsLoader.loaders.unshift('monkey-hot'); -} - -/** - * Process AssetsPlugin output and format it - * for Sage: {"[name].[ext]":"[name]_[hash].[ext]"} - * @param {Object} assets passed by processOutput - * @return {String} JSON - */ -var assetsPluginProcessOutput = function (assets) { - var name, - ext, - filename, - results = {}; - - for (name in assets) { - if (assets.hasOwnProperty(name)) { - for (ext in assets[name]) { - if (assets[name].hasOwnProperty(ext)) { - filename = name + '.' + ext; - results[filename] = path.basename(assets[name][ext]); - } - } - } - } - return JSON.stringify(results); -}; - -/** - * Loop through webpack entry - * and add the hot middleware - * @param {Object} entry webpack entry - * @return {Object} entry with hot middleware - */ -var addHotMiddleware = function (entry) { - var name, - results = {}, - hotMiddlewareScript = 'webpack-hot-middleware/client?' + qs.stringify({ - timeout: 20000, - reload: true - }); - - for (name in entry) { - if (entry.hasOwnProperty(name)) { - if (entry[name] instanceof Array !== true) { - results[name] = [entry[name]]; - } else { - results[name] = entry[name].slice(0); - } - results[name].push(hotMiddlewareScript); - } - } - return results; -}; - -webpackConfig = { - context: path.resolve(assets), - entry: config.entry, - output: { - path: path.join(__dirname, dist), - publicPath: path.join(config.publicPath, dist), - filename: scriptsFilename - }, - module: { - preLoaders: [ - { - test: /\.js?$/, - include: path.resolve(assets), - loader: 'eslint' - } - ], - loaders: [ - jsLoader, - { - test: /\.css$/, - include: path.resolve(assets), - loader: ExtractTextPlugin.extract('style', [ - 'css?' + sourceMapQueryStr, - 'postcss' - ]) - }, - { - test: /\.scss$/, - include: path.resolve(assets), - loader: ExtractTextPlugin.extract('style', [ - 'css?' + sourceMapQueryStr, - 'postcss', - 'resolve-url?' + sourceMapQueryStr, - 'sass?' + sourceMapQueryStr - ]) - }, - { - test: /\.(png|jpg|jpeg|gif|svg)(\?.*)?$/, - include: path.resolve(assets), - loaders: [ - 'file?' + qs.stringify({ - name: '[path][name].[ext]' - }), - 'image-webpack?' + JSON.stringify({ - bypassOnDebug: true, - progressive: true, - optimizationLevel: 7, - interlaced: true, - pngquant: { - quality: "65-90", - speed: 4 - }, - svgo: { - removeUnknownsAndDefaults: false, - cleanupIDs: false - } - }) - ] - }, - { - test: /\.(ttf|eot)(\?.*)?$/, - include: path.resolve(assets), - loader: 'file?' + qs.stringify({ - name: '[path][name]_[md5:hash:hex:8].[ext]' - }) - }, - { - test: /\.woff(2)?(\?.*)?$/, - include: path.resolve(assets), - loader: 'url?' + qs.stringify({ - limit: 10000, - mimetype: "application/font-woff", - name: "[path][name]_[md5:hash:hex:8].[ext]" - }) - }, - // Use file-loader for node_modules/ assets - { - test: /\.(ttf|eot|woff(2)?|png|jpg|jpeg|gif|svg)(\?.*)?$/, - include: /node_modules/, - loader: 'file?' + qs.stringify({ - name: 'vendor/[name]_[md5:hash:hex:8].[ext]' - }) - } - ] - }, - resolve: { - extensions: [ '', '.js', '.json' ], - modulesDirectories: [ - 'node_modules', - 'bower_components' - ] - }, - externals: { - jquery: 'jQuery' - }, - plugins: [ - new Clean([dist]), - new ExtractTextPlugin(stylesFilename, { - allChunks: true, - disable: (argv.watch === true) // '--watch' disable ExtractTextPlugin - }), - new webpack.ProvidePlugin({ - $: 'jquery', - jQuery: 'jquery', - 'window.jQuery': 'jquery', - 'Tether': 'tether', - 'window.Tether': 'tether' - }), - new webpack.DefinePlugin({ - WEBPACK_PUBLIC_PATH: (argv.watch === true) ? JSON.stringify(path.join(config.publicPath, dist)) : false - }) - ], - postcss: [ - autoprefixer({ - browsers: [ - 'last 2 versions', - 'android 4', - 'opera 12' - ] - }) - ], - eslint: { - failOnWarning: false, - failOnError: true - }, - stats: { - colors: true - } -}; - -// '--watch' to push additional plugins to webpackConfig -if (argv.watch) { - webpackConfig.entry = addHotMiddleware(webpackConfig.entry); - webpackConfig.output.pathinfo = true; - webpackConfig.debug = true; - webpackConfig.devtool = '#cheap-module-source-map'; - webpackConfig.plugins.push(new webpack.optimize.OccurenceOrderPlugin()); - webpackConfig.plugins.push(new webpack.HotModuleReplacementPlugin()); - webpackConfig.plugins.push(new webpack.NoErrorsPlugin()); -} - -// '--release' to push additional plugins to webpackConfig -if (argv.release) { - webpackConfig.plugins.push(new AssetsPlugin({ - path: path.join(__dirname, dist), - filename: 'assets.json', - fullPath: false, - processOutput: assetsPluginProcessOutput - })); - webpackConfig.plugins.push(new webpack.optimize.UglifyJsPlugin({ - compress: { - 'drop_debugger': true - } - })); - webpackConfig.plugins.push(new OptimizeCssAssetsPlugin({ - cssProcessor: cssnano, - cssProcessorOptions: { discardComments: { removeAll: true } }, - canPrint: true - })); -} - -module.exports = webpackConfig;