From edfd24bf63e8b3f678272972adef3e38ba36ff01 Mon Sep 17 00:00:00 2001 From: Sheng Di Date: Wed, 7 Feb 2018 12:31:08 -0800 Subject: [PATCH] [minor] component archetype extract styles (#713) * Update component archetype extract-styles * update archetype config path --- .../config/webpack/partial/extract-style.js | 138 ++++++++++++------ .../package.json | 12 +- 2 files changed, 97 insertions(+), 53 deletions(-) diff --git a/packages/electrode-archetype-react-component-dev/config/webpack/partial/extract-style.js b/packages/electrode-archetype-react-component-dev/config/webpack/partial/extract-style.js index 38b4454aa..882369171 100644 --- a/packages/electrode-archetype-react-component-dev/config/webpack/partial/extract-style.js +++ b/packages/electrode-archetype-react-component-dev/config/webpack/partial/extract-style.js @@ -5,83 +5,125 @@ const glob = require("glob"); const atImport = require("postcss-import"); const cssnext = require("postcss-cssnext"); +const webpack = require("webpack"); + const styleLoader = require.resolve("style-loader"); const cssLoader = require.resolve("css-loader"); const postcssLoader = require.resolve("postcss-loader"); const stylusLoader = require.resolve("stylus-relative-loader"); -const webpack = require("webpack"); +const sassLoader = require.resolve("sass-loader"); -const optionalRequire = require("optional-require")(require); -const configPath = Path.resolve("archetype", "config.js"); -const config = optionalRequire(configPath); -const cssModuleStylusSupport = config && config.cssModuleStylusSupport; +const demoAppPath = Path.resolve(process.cwd(), "..", "..", "demo-app"); +const archetypeAppPath = Path.resolve( + demoAppPath, + "archetype", + "config" +); +const archetypeAppWebpack = require(archetypeAppPath).webpack; +let cssModuleSupport = archetypeAppWebpack.cssModuleSupport; +const cssModuleStylusSupport = archetypeAppWebpack.cssModuleStylusSupport; -/** - * [cssModuleSupport By default, this archetype assumes you are using CSS-Modules + CSS-Next] - * - * Stylus is also supported for which the following cases can occur. +/* + * cssModuleSupport: false + * case 1: *only* *.css => normal CSS + * case 2: *only* *.styl exists => Stylus + * case 3: *only* *.scss exists => SASS * - * case 1: *only* demo.css exists => CSS-Modules + CSS-Next - * case 2: *only* demo.styl exists => stylus - * case 3: *both* demo.css & demo.styl exists => CSS-Modules + CSS-Next takes priority - * with a warning message - * case 4: *none* demo.css & demo.styl exists => CSS-Modules + CSS-Next takes priority - * case 5: *cssModuleStylusSupport + * cssModulesSupport: true + * case 1: *only* *.css => CSS-Modules + CSS-Next + * case 2: *only* *.styl => normal CSS => CSS-Modules + CSS-Next + * case 3: *only* *.scss => normal CSS => CSS-Modules + CSS-Next */ -const cssNextExists = glob.sync(Path.join(process.cwd() + "/demo/*.css")).length > 0; -const stylusExists = glob.sync(Path.join(process.cwd() + "/demo/*.styl")).length > 0; +const cssLoaderOptions = + "?modules&localIdentName=[name]__[local]___[hash:base64:5]&-autoprefixer"; +const cssQuery = `${cssLoader}!${postcssLoader}`; +const stylusQuery = `${cssLoader}?-autoprefixer!${stylusLoader}`; +const scssQuery = `${cssQuery}!${sassLoader}`; +const cssModuleQuery = `${cssLoader}${cssLoaderOptions}!${postcssLoader}`; +const cssStylusQuery = `${cssLoader}${cssLoaderOptions}!${postcssLoader}!${stylusLoader}`; +const cssScssQuery = `${cssLoader}${cssLoaderOptions}!${postcssLoader}!${sassLoader}`; -// By default, this archetype assumes you are using CSS-Modules + CSS-Next -let cssModuleSupport = "?modules!" + postcssLoader; +const cssExists = + glob.sync(Path.resolve(process.cwd(), "src/styles", "*.css")).length > 0; +const stylusExists = + glob.sync(Path.resolve(process.cwd(), "src/styles", "*.styl")).length > 0; +const scssExists = + glob.sync(Path.resolve(process.cwd(), "src/styles", "*.scss")).length > 0; -if (stylusExists && !cssNextExists) { - cssModuleSupport = ""; -} else if (stylusExists && cssNextExists) { - /* eslint-disable no-console */ - console.log(`**** you have demo.css & demo.styl please delete *.styl - and upgrade to using *.css for CSS-Modules + CSS-Next support ****`); - /* eslint-enable no-console */ +const rules = []; + +/* + * cssModuleSupport default to undefined + * + * when cssModuleSupport not specified: + * *only* *.css, cssModuleSupport sets to true + * *only* *.styl, cssModuleSupport sets to false + * *only* *.scss, cssModuleSupport sets to false + */ +if (cssModuleSupport === undefined) { + cssModuleSupport = cssExists && !stylusExists && !scssExists; } module.exports = function() { - const loaders = [{ - test: /\.css$/, - /* eslint-disable prefer-template */ - loader: styleLoader + "!" + cssLoader + cssModuleSupport - /* eslint-enable prefer-template */ - }]; + rules.push( + { + test: /\.css$/, + use: cssModuleSupport ? cssModuleQuery : cssQuery + }, + { + test: /\.scss$/, + use: cssModuleSupport ? cssScssQuery : scssQuery + }, + { + test: /\.styl$/, + use: cssModuleSupport ? cssStylusQuery : stylusQuery + } + ); + /* + *** cssModuleStylusSupport flag is about to deprecate. *** + * If you want to enable stylus with CSS-Modules + CSS-Next, + * Please use stylus as your style and enable cssModuleSupport flag instead. + */ if (cssModuleStylusSupport) { - loaders.push({ + rules.push({ test: /\.styl$/, - /* eslint-disable prefer-template */ - loader: styleLoader + "!" + cssLoader + "?modules!" + stylusLoader - /* eslint-enable prefer-template */ - }); - } else { - loaders.push({ - test: /\.styl$/, - /* eslint-disable prefer-template */ - loader: styleLoader + "!" + cssLoader + "!" + stylusLoader - /* eslint-enable prefer-template */ + use: cssStylusQuery }); } return { - module: { - rules: loaders - }, + module: { rules }, plugins: [ new webpack.LoaderOptionsPlugin({ options: { + postcss: () => { + return cssModuleSupport + ? [ + atImport, + cssnext({ + browsers: ["last 2 versions", "ie >= 9", "> 5%"] + }) + ] + : []; + }, stylus: { + use: () => { + return !cssModuleSupport + ? [ + autoprefixer({ + browsers: ["last 2 versions", "ie >= 9", "> 5%"] + }) + ] + : []; + }, define: { $tenant: process.env.ELECTRODE_TENANT || "walmart" } } } }) - ] - } + ].filter(x => !!x) + }; }; diff --git a/packages/electrode-archetype-react-component-dev/package.json b/packages/electrode-archetype-react-component-dev/package.json index a62629058..203351578 100644 --- a/packages/electrode-archetype-react-component-dev/package.json +++ b/packages/electrode-archetype-react-component-dev/package.json @@ -33,7 +33,7 @@ "chalk": "^1.1.3", "component-playground": "^3.0.0", "config": "^1.19.0", - "css-loader": "^0.26.1", + "css-loader": "^0.28.9", "electrode-check-dependencies": "^1.0.2", "electrode-demo-index": "^1.0.0", "electrode-docgen": "^1.0.0", @@ -50,7 +50,7 @@ "husky": "^0.13.4", "isparta": "^4.0.0", "istanbul": "^0.4.5", - "json-loader": "^0.5.3", + "json-loader": "^0.5.7", "jsonfile": "^2.2.2", "karma": "^1.5.0", "karma-chrome-launcher": "^2.1.1", @@ -70,6 +70,7 @@ "lodash-webpack-plugin": "^0.11.2", "mocha": "^4.0.0", "nodemon": "^1.8.1", + "node-sass": "^4.7.2", "optional-require": "^1.0.0", "phantomjs-prebuilt": "^2.1.13", "postcss-cssnext": "^2.7.0", @@ -84,13 +85,14 @@ "react-test-renderer": "^16.0.0", "require-at": "^1.0.0", "rimraf": "^2.5.2", + "sass-loader": "^6.0.6", "sinon": "^4.0.0", "sinon-chai": "^2.14.0", - "style-loader": "^0.13.1", + "style-loader": "^0.20.1", "stylint": "^1.3.6", "stylus": "^0.54.5", - "stylus-relative-loader": "^3.0.0", - "url-loader": "^0.5.6", + "stylus-relative-loader": "^3.4.0", + "url-loader": "^0.6.2", "webpack": "^3.0.0", "webpack-config-composer": "^1.0.2", "webpack-dev-server": "^2.7.1",