From 7ef456a1e617ba989d6189a20d3cb5ddec2d2365 Mon Sep 17 00:00:00 2001 From: Raissa North Date: Mon, 29 Jan 2018 11:46:54 +1300 Subject: [PATCH] API Convert gulp and Compass builds to use Webpack --- .eslintrc.js | 1 + .gitignore | 5 +- .sass-lint.yml | 179 ++++++++++++++ client/dist/js/main.bundle.js | 221 ++++++++++++++++++ client/dist/styles/main.css | 2 + {js => client/src/bundles}/cms.js | 0 .../src/bundles}/gridfieldaddbydbfield.js | 0 client/src/main.js | 2 + client/src/main.scss | 2 + {scss => client/src/styles}/blog.scss | 0 {scss => client/src/styles}/cms.scss | 14 +- config.rb | 25 -- gulpfile.js | 17 -- package.json | 26 ++- scss/categories-tags.scss | 0 webpack.config.js | 55 +++++ 16 files changed, 480 insertions(+), 69 deletions(-) create mode 100644 .eslintrc.js create mode 100644 .sass-lint.yml create mode 100644 client/dist/js/main.bundle.js create mode 100644 client/dist/styles/main.css rename {js => client/src/bundles}/cms.js (100%) rename {js => client/src/bundles}/gridfieldaddbydbfield.js (100%) create mode 100644 client/src/main.js create mode 100644 client/src/main.scss rename {scss => client/src/styles}/blog.scss (100%) rename {scss => client/src/styles}/cms.scss (92%) delete mode 100644 config.rb delete mode 100644 gulpfile.js delete mode 100644 scss/categories-tags.scss create mode 100644 webpack.config.js diff --git a/.eslintrc.js b/.eslintrc.js new file mode 100644 index 0000000..4b81cff --- /dev/null +++ b/.eslintrc.js @@ -0,0 +1 @@ +module.exports = require('@silverstripe/eslint-config/.eslintrc'); diff --git a/.gitignore b/.gitignore index 3b7b7c6..80e016d 100755 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,5 @@ -.ssh/* -.bash* -.profile /vendor/* .sass-cache/* /node_modules/ +**/*.js.map +**/*.css.map diff --git a/.sass-lint.yml b/.sass-lint.yml new file mode 100644 index 0000000..4cb623f --- /dev/null +++ b/.sass-lint.yml @@ -0,0 +1,179 @@ +# sass-lint config to match the AirBNB style guide +# See silverstripe-admin +files: + include: '**/client/src/**/*.scss' + ignore: + - 'client/src/styles/legacy/*' + - 'src/**/*' +options: + formatter: stylish + merge-default-rules: false +rules: + # Warnings + # Things that require actual refactoring are marked as warnings + class-name-format: + - 1 + - convention: hyphenatedbem + placeholder-name-format: + - 1 + - convention: hyphenatedlowercase + nesting-depth: + - 1 + - max-depth: 3 + no-ids: 1 + no-important: 1 + no-misspelled-properties: + - 1 + - extra-properties: + - "-moz-border-radius-topleft" + - "-moz-border-radius-topright" + - "-moz-border-radius-bottomleft" + - "-moz-border-radius-bottomright" + variable-name-format: + - 1 + - allow-leading-underscore: true + convention: hyphenatedlowercase + no-extends: 1 + + # Warnings: these things are preferential rather than mandatory + no-css-comments: 1 + + # Errors + # Things that can be easily fixed are marked as errors + indentation: + - 2 + - size: 2 + final-newline: + - 2 + - include: true + no-trailing-whitespace: 2 + border-zero: + - 2 + - convention: '0' + brace-style: + - 2 + - allow-single-line: true + clean-import-paths: + - 2 + - filename-extension: false + leading-underscore: false + no-debug: 2 + no-empty-rulesets: 2 + no-invalid-hex: 2 + no-mergeable-selectors: 2 + # no-qualifying-elements: + # - 1 + # - allow-element-with-attribute: false + # allow-element-with-class: false + # allow-element-with-id: false + no-trailing-zero: 2 + no-url-protocols: 2 + quotes: + - 2 + - style: double + space-after-bang: + - 2 + - include: false + space-after-colon: + - 2 + - include: true + space-after-comma: + - 2 + - include: true + space-before-bang: + - 2 + - include: true + space-before-brace: + - 2 + - include: true + space-before-colon: 2 + space-between-parens: + - 2 + - include: false + trailing-semicolon: 2 + url-quotes: 2 + zero-unit: 2 + single-line-per-selector: 2 + one-declaration-per-line: 2 + empty-line-between-blocks: + - 2 + - ignore-single-line-rulesets: true + + + # Missing rules + # There are no sass-lint rules for the following AirBNB style items, but thess + # - Put comments on their own line + # - Put property delcarations before mixins + + # Disabled rules + + # These are other rules that we may wish to consider using in the future + # They are not part of the AirBNB CSS standard but they would introduce some strictness + # bem-depth: 0 + # variable-for-property: 0 + # no-transition-all: 0 + # hex-length: + # - 1 + # - style: short + # hex-notation: + # - 1 + # - style: lowercase + # property-units: + # - 1 + # - global: + # - ch + # - em + # - ex + # - rem + # - cm + # - in + # - mm + # - pc + # - pt + # - px + # - q + # - vh + # - vw + # - vmin + # - vmax + # - deg + # - grad + # - rad + # - turn + # - ms + # - s + # - Hz + # - kHz + # - dpi + # - dpcm + # - dppx + # - '%' + # per-property: {} + # force-attribute-nesting: 1 + # force-element-nesting: 1 + # force-pseudo-nesting: 1 + # function-name-format: + # - 1 + # - allow-leading-underscore: true + # convention: hyphenatedlowercase + # no-color-literals: 1 + # no-duplicate-properties: 1 + # mixin-name-format: + # - 1 + # - allow-leading-underscore: true + # convention: hyphenatedlowercase + # shorthand-values: + # - 1 + # - allowed-shorthands: + # - 1 + # - 2 + # - 3 + # leading-zero: + # - 1 + # - include: false + # no-vendor-prefixes: + # - 1 + # - additional-identifiers: [] + # excluded-identifiers: [] + # placeholder-in-extend: 1 + # no-color-keywords: 2 diff --git a/client/dist/js/main.bundle.js b/client/dist/js/main.bundle.js new file mode 100644 index 0000000..d71d585 --- /dev/null +++ b/client/dist/js/main.bundle.js @@ -0,0 +1,221 @@ +/******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) { +/******/ return installedModules[moduleId].exports; +/******/ } +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ i: moduleId, +/******/ l: false, +/******/ exports: {} +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.l = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // identity function for calling harmony imports with the correct context +/******/ __webpack_require__.i = function(value) { return value; }; +/******/ +/******/ // define getter function for harmony exports +/******/ __webpack_require__.d = function(exports, name, getter) { +/******/ if(!__webpack_require__.o(exports, name)) { +/******/ Object.defineProperty(exports, name, { +/******/ configurable: false, +/******/ enumerable: true, +/******/ get: getter +/******/ }); +/******/ } +/******/ }; +/******/ +/******/ // getDefaultExport function for compatibility with non-harmony modules +/******/ __webpack_require__.n = function(module) { +/******/ var getter = module && module.__esModule ? +/******/ function getDefault() { return module['default']; } : +/******/ function getModuleExports() { return module; }; +/******/ __webpack_require__.d(getter, 'a', getter); +/******/ return getter; +/******/ }; +/******/ +/******/ // Object.prototype.hasOwnProperty.call +/******/ __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(__webpack_require__.s = 3); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ (function(module, exports) { + +module.exports = jQuery; + +/***/ }), +/* 1 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(jQuery) {(function ($) { + + $.entwine('ss', function ($) { + $('.cms-content-fields > #Form_EditForm_error').entwine({ + 'onadd': function onadd() { + var $target = $('.blog-admin-outer'); + if ($target.length == 1) { + $target.prepend(this); + } + } + }); + + $('.toggle-description').entwine({ + 'onadd': function onadd() { + var $this = $(this); + + if ($this.hasClass('toggle-description-enabled')) { + return; + } + + $this.addClass('toggle-description-enabled'); + + var shown = false; + var $helpInfo = $this.closest('.field').find('.form-text'); + + $this.on('click', function () { + $helpInfo[shown ? 'hide' : 'show'](); + $this.toggleClass('toggle-description-shown'); + shown = !shown; + }); + + $helpInfo.hide(); + + $this.parent().addClass('toggle-description-correct-right'); + $this.parent().prev('.middleColumn').addClass('toggle-description-correct-middle'); + $this.parent().next('.description').addClass('toggle-description-correct-description'); + } + }); + + $('.MergeAction').entwine({ + 'onadd': function onadd() { + var $this = $(this); + + $this.on('click', 'select', function () { + return false; + }); + + $this.children('button').each(function (i, button) { + var $button = $(button); + var $select = $button.prev('select'); + + $button.before(''); + }); + + $this.on('change', 'select', function (e) { + var $target = $(e.target); + + $target.next('input').val($target.val()); + }); + + $this.children('button, select').hide(); + + $this.on('click', '.MergeActionReveal', function (e) { + var $target = $(e.target); + + $target.parent().children('button, select').show(); + $target.hide(); + + return false; + }); + } + }); + + $('.blog-admin-sidebar.cms-panel').entwine({ + MinInnerWidth: 620, + onadd: function onadd() { + this._super(); + this.updateLayout(); + + if (!this.hasClass('collapsed') && $(".blog-admin-outer").width() < this.getMinInnerWidth()) { + this.collapsePanel(); + } + + window.onresize = function () { + this.updateLayout(); + }.bind(this); + }, + togglePanel: function togglePanel(bool, silent) { + this._super(bool, silent); + this.updateLayout(); + }, + + updateLayout: function updateLayout() { + $(this).css('height', '100%'); + var currentHeight = $(this).outerHeight(); + var bottomHeight = $('.cms-content-actions').eq(0).outerHeight(); + $(this).css('height', currentHeight - bottomHeight + "px"); + $(this).css('bottom', bottomHeight + "px"); + + $('.cms-container').updateLayoutOptions({ + minContentWidth: 820 + this.width() + }); + } + }); + }); +})(jQuery); +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) + +/***/ }), +/* 2 */ +/***/ (function(module, exports, __webpack_require__) { + +/* WEBPACK VAR INJECTION */(function(jQuery) {(function ($) { + $.entwine('ss', function ($) { + $('.add-existing-autocompleter input.text').entwine({ + 'onkeydown': function onkeydown(e) { + if (e.which == 13) { + $parent = $(this).parents('.add-existing-autocompleter'); + $parent.find('button[type="submit"]').click(); + return false; + } + } + }); + }); +})(jQuery); +/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(0))) + +/***/ }), +/* 3 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + +"use strict"; +Object.defineProperty(__webpack_exports__, "__esModule", { value: true }); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_bundles_cms_js__ = __webpack_require__(1); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_bundles_cms_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_0_bundles_cms_js__); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_bundles_gridfieldaddbydbfield_js__ = __webpack_require__(2); +/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1_bundles_gridfieldaddbydbfield_js___default = __webpack_require__.n(__WEBPACK_IMPORTED_MODULE_1_bundles_gridfieldaddbydbfield_js__); + + + +/***/ }) +/******/ ]); +//# sourceMappingURL=main.bundle.js.map \ No newline at end of file diff --git a/client/dist/styles/main.css b/client/dist/styles/main.css new file mode 100644 index 0000000..4a5ba9d --- /dev/null +++ b/client/dist/styles/main.css @@ -0,0 +1,2 @@ +.no-sidebar .content-container.size3of4{width:75%}.blog-entry .post-image img{width:98.75%}.blog-sidebar .WidgetHolder ul{margin-left:0}.blog-sidebar .WidgetHolder ul li,ul.blogTagCloud{list-style-type:none}ul.blogTagCloud{clear:both}ul.blogTagCloud li{float:left;display:inline;padding-right:8px}ul.blogTagCloud li a span{float:left;line-height:30px;text-align:center;padding:0}ul.blogTagCloud .tagCount10{font-size:26pt}ul.blogTagCloud .tagCount9{font-size:24pt}ul.blogTagCloud .tagCount8{font-size:22pt}ul.blogTagCloud .tagCount7{font-size:20pt}ul.blogTagCloud .tagCount6{font-size:18pt}ul.blogTagCloud .tagCount5{font-size:16pt}ul.blogTagCloud .tagCount4{font-size:14pt}ul.blogTagCloud .tagCount3{font-size:12pt}ul.blogTagCloud .tagCount2{font-size:10pt}ul.blogTagCloud .tagCount1{font-size:8pt}#FeaturedImage .middleColumn{clear:none;float:left}.has-panel .cms-content-tools.blog-admin-sidebar{width:280px;border-right:none;border-left:1px solid #c0c0c2;position:absolute!important;right:0;top:0;height:100%}.has-panel .cms-content-tools.blog-admin-sidebar .cms-panel-toggle a{text-align:left;margin:0}.has-panel .cms-content-tools.blog-admin-sidebar .cms-panel-toggle.south{border-top:1px solid #aaa}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer{width:100%;padding-right:280px;position:absolute;height:100%;overflow-y:hidden;overflow-x:hidden;-webkit-box-sizing:border-box;box-sizing:border-box}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset{position:relative;overflow:auto;height:100%;width:100%}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset #Title label{float:none}.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset #Title .middleColumn,.has-panel .cms-content-tools.blog-admin-sidebar~.blog-admin-outer>.ss-tabset #Title input{width:100%;max-width:100%;margin-left:0}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field+.field{margin-top:10px}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.urlsegment .preview{padding-top:0;line-height:25px}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.urlsegment .edit{float:right}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn>.date{width:60%}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn>.time{width:36%;float:right}.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn .middleColumn,.has-panel .cms-content-tools.blog-admin-sidebar .cms-content-view>.field.datetime>.middleColumn input{width:100%}.has-panel .cms-content-tools.blog-admin-sidebar.collapsed~.blog-admin-outer{padding-right:41px}.has-panel .cms-content-tools.blog-admin-sidebar.collapsed~.blog-admin-outer #Root_Main{margin-right:15px}.has-panel .cms-content-tools.blog-admin-sidebar.cms-content-tools .cms-panel-content{width:auto}.toggle-description{text-indent:-1000000px;display:inline-block;width:20px;height:20px;margin-left:4px;cursor:pointer}.middleColumn.toggle-description-correct-middle{margin-left:0;float:left;width:416px}.tab-content .field p.toggle-description-correct-right{display:inline-block;margin-left:0;padding-left:0;clear:none;float:left}.description.toggle-description-correct-description{width:416px;padding:12px 0}.custom-summary .ui-accordion-content .field{margin:0}.custom-summary .ui-accordion-content,.custom-summary .ui-accordion-content .field{padding:0}.custom-summary .ui-icon-triangle-1-e{background-position:-16px -128px}.cms table.ss-gridfield-table tr td.MergeAction{width:225px}.cms table.ss-gridfield-table tr td.MergeAction a{display:block;height:100%;width:100%}.cms table.ss-gridfield-table tr td.MergeAction select{width:150px}.cms-content-actions,.cms-preview-controls{z-index:999}.blog-cms-categorisation .MergeActionReveal{margin-left:10px}.blog-cms-categorisation .toolbar--content{margin-top:0}.blog-cms-categorisation .MergeActionReveal:after{content:"";display:inline-block;height:16px;width:16px;margin-left:4px}.blog-cms-categorisation button.action{margin-left:5px} +/*# sourceMappingURL=main.css.map*/ \ No newline at end of file diff --git a/js/cms.js b/client/src/bundles/cms.js similarity index 100% rename from js/cms.js rename to client/src/bundles/cms.js diff --git a/js/gridfieldaddbydbfield.js b/client/src/bundles/gridfieldaddbydbfield.js similarity index 100% rename from js/gridfieldaddbydbfield.js rename to client/src/bundles/gridfieldaddbydbfield.js diff --git a/client/src/main.js b/client/src/main.js new file mode 100644 index 0000000..d33d3b6 --- /dev/null +++ b/client/src/main.js @@ -0,0 +1,2 @@ +import 'bundles/cms.js'; +import 'bundles/gridfieldaddbydbfield.js'; diff --git a/client/src/main.scss b/client/src/main.scss new file mode 100644 index 0000000..471ecdb --- /dev/null +++ b/client/src/main.scss @@ -0,0 +1,2 @@ +@import "styles/blog"; +@import "styles/cms"; diff --git a/scss/blog.scss b/client/src/styles/blog.scss similarity index 100% rename from scss/blog.scss rename to client/src/styles/blog.scss diff --git a/scss/cms.scss b/client/src/styles/cms.scss similarity index 92% rename from scss/cms.scss rename to client/src/styles/cms.scss index 478c037..84c2b37 100755 --- a/scss/cms.scss +++ b/client/src/styles/cms.scss @@ -1,16 +1,6 @@ /** * CMS Styles */ -/** - * Include Compass framework - */ -// @import "compass"; -/* - * Sprite maps & Icons - */ -// @import "compass/utilities/sprites/base"; -// @import "blog-icon/*.png"; -// buttons #FeaturedImage .middleColumn { clear: none; @@ -120,7 +110,7 @@ .toggle-description { text-indent: -1000000px; display: inline-block; - background: url("../images/information.png") no-repeat center center; + //background: url("../images/information.png") no-repeat center center; width: 20px; height: 20px; margin-left: 4px; @@ -193,7 +183,7 @@ .MergeActionReveal:after { content: ''; - background: url('../images/move-icon.png'); + //background: url('../images/move-icon.png'); display: inline-block; height: 16px; width: 16px; diff --git a/config.rb b/config.rb deleted file mode 100644 index c06ea53..0000000 --- a/config.rb +++ /dev/null @@ -1,25 +0,0 @@ -require 'compass/import-once/activate' -# Require any additional compass plugins here. - -# Set this to the root of your project when deployed: -http_path = "/" -css_dir = "css" -sass_dir = "scss" -images_dir = "images" -javascripts_dir = "javascripts" - -# You can select your preferred output style here (can be overridden via the command line): -output_style = :nested - -# To enable relative paths to assets via compass helper functions. Uncomment: -# relative_assets = true - -# To disable debugging comments that display the original location of your selectors. Uncomment: -line_comments = false - - -# If you prefer the indented syntax, you might want to regenerate this -# project again passing --syntax sass, or you can uncomment this: -# preferred_syntax = :sass -# and then run: -# sass-convert -R --from scss --to sass sass scss && rm -rf sass && mv scss sass diff --git a/gulpfile.js b/gulpfile.js deleted file mode 100644 index 819222d..0000000 --- a/gulpfile.js +++ /dev/null @@ -1,17 +0,0 @@ -var sass = require("gulp-sass"); -var gulp = require("gulp"); -var watch = require('gulp-watch'); - -gulp.task("scss", function () { - gulp.src("./scss/*.scss") - .pipe(sass().on('error', sass.logError)) - .pipe(gulp.dest("./css")); -}); - -gulp.task('watch', ['scss'], function () { - gulp.watch('./scss/*.scss', ['scss']); -}); - -gulp.task('default', ['scss'], function () { - // noop -}); diff --git a/package.json b/package.json index 4fe994b..6ca65e0 100644 --- a/package.json +++ b/package.json @@ -1,28 +1,30 @@ { "name": "silverstripe-blog", "version": "3.0.0", - "description": "Silverstripe blog module", - "main": "index.js", - "directories": { - "doc": "docs", - "test": "tests" - }, + "description": "A fresh take on blogging in Silverstripe set out to tackle the issue of a cluttered Site Tree", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "yarn && NODE_ENV=production webpack -p --bail --progress", + "watch": "yarn && NODE_ENV=development webpack --watch --progress", + "css": "WEBPACK_CHILD=css npm run build", + "lint": "eslint client/src; sass-lint -v" }, "repository": { "type": "git", "url": "git+https://github.com/silverstripe/silverstripe-blog.git" }, - "author": "", - "license": "BSD-3", + "keywords": [ + "silverstripe", + "blog" + ], + "author": "SilverStripe Ltd", + "license": "BSD-2-Clause", "bugs": { "url": "https://github.com/silverstripe/silverstripe-blog/issues" }, "homepage": "https://github.com/silverstripe/silverstripe-blog#readme", + "dependencies": [], "devDependencies": { - "gulp": "^3.9.1", - "gulp-sass": "^2.3.1", - "gulp-watch": "^4.3.6" + "@silverstripe/eslint-config": "^0.0.4", + "@silverstripe/webpack-config": "^0.5" } } diff --git a/scss/categories-tags.scss b/scss/categories-tags.scss deleted file mode 100644 index e69de29..0000000 diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..45b855a --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,55 @@ +const Path = require('path'); +const webpack = require('webpack'); +// Import the core config +const webpackConfig = require('@silverstripe/webpack-config'); +const { + resolveJS, + externalJS, + moduleJS, + pluginJS, + moduleCSS, + pluginCSS, +} = webpackConfig; + +const ENV = process.env.NODE_ENV; +const PATHS = { + ROOT: Path.resolve(), + MODULES: 'node_modules', + FILES_PATH: '../', + THIRDPARTY: 'thirdparty', + SRC: Path.resolve('client/src'), + DIST: Path.resolve('client/dist'), +}; + +const config = [ + { + name: 'bundle', + entry: { + main: `${PATHS.SRC}/main.js` + }, + output: { + path: PATHS.DIST, + filename: 'js/[name].bundle.js', + }, + devtool: (ENV !== 'production') ? 'source-map' : '', + resolve: resolveJS(ENV, PATHS), + externals: externalJS(ENV, PATHS), + module: moduleJS(ENV, PATHS), + plugins: pluginJS(ENV, PATHS), + }, + { + name: 'bundle', + entry: { + main: `${PATHS.SRC}/main.scss` + }, + output: { + path: PATHS.DIST, + filename: 'styles/[name].css' + }, + devtool: (ENV !== 'production') ? 'source-map' : '', + module: moduleCSS(ENV, PATHS), + plugins: pluginCSS(ENV, PATHS), + }, +]; + +module.exports = config;