"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = require("path"); const suppress_entry_chunks_webpack_plugin_1 = require("../../plugins/suppress-entry-chunks-webpack-plugin"); const utils_1 = require("./utils"); const eject_1 = require("../../tasks/eject"); const cssnano = require('cssnano'); const postcssUrl = require('postcss-url'); const autoprefixer = require('autoprefixer'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); const customProperties = require('postcss-custom-properties'); /** * Enumerate loaders and their dependencies from this file to let the dependency validator * know they are used. * * require('exports-loader') * require('style-loader') * require('postcss-loader') * require('css-loader') * require('stylus') * require('stylus-loader') * require('less') * require('less-loader') * require('node-sass') * require('sass-loader') */ function getStylesConfig(wco) { const { projectRoot, buildOptions, appConfig } = wco; const appRoot = path.resolve(projectRoot, appConfig.root); const entryPoints = {}; const globalStylePaths = []; const extraPlugins = []; // style-loader does not support sourcemaps without absolute publicPath, so it's // better to disable them when not extracting css // https://github.com/webpack-contrib/style-loader#recommended-configuration const cssSourceMap = buildOptions.extractCss && buildOptions.sourcemaps; // Minify/optimize css in production. const minimizeCss = buildOptions.target === 'production'; // Convert absolute resource URLs to account for base-href and deploy-url. const baseHref = wco.buildOptions.baseHref || ''; const deployUrl = wco.buildOptions.deployUrl || ''; const postcssPluginCreator = function () { // safe settings based on: https://github.com/ben-eb/cssnano/issues/358#issuecomment-283696193 const importantCommentRe = /@preserve|@license|[@#]\s*source(?:Mapping)?URL|^!/i; const minimizeOptions = { autoprefixer: false, safe: true, mergeLonghand: false, discardComments: { remove: (comment) => !importantCommentRe.test(comment) } }; return [ postcssUrl({ url: (URL) => { const { url } = URL; // Only convert root relative URLs, which CSS-Loader won't process into require(). if (!url.startsWith('/') || url.startsWith('//')) { return URL.url; } if (deployUrl.match(/:\/\//)) { // If deployUrl contains a scheme, ignore baseHref use deployUrl as is. return `${deployUrl.replace(/\/$/, '')}${url}`; } else if (baseHref.match(/:\/\//)) { // If baseHref contains a scheme, include it as is. return baseHref.replace(/\/$/, '') + `/${deployUrl}/${url}`.replace(/\/\/+/g, '/'); } else { // Join together base-href, deploy-url and the original URL. // Also dedupe multiple slashes into single ones. return `/${baseHref}/${deployUrl}/${url}`.replace(/\/\/+/g, '/'); } } }), autoprefixer(), customProperties({ preserve: true }) ].concat(minimizeCss ? [cssnano(minimizeOptions)] : []); }; postcssPluginCreator[eject_1.postcssArgs] = { variableImports: { 'autoprefixer': 'autoprefixer', 'postcss-url': 'postcssUrl', 'cssnano': 'cssnano', 'postcss-custom-properties': 'customProperties' }, variables: { minimizeCss, baseHref, deployUrl } }; // determine hashing format const hashFormat = utils_1.getOutputHashFormat(buildOptions.outputHashing); // use includePaths from appConfig const includePaths = []; let lessPathOptions; if (appConfig.stylePreprocessorOptions && appConfig.stylePreprocessorOptions.includePaths && appConfig.stylePreprocessorOptions.includePaths.length > 0) { appConfig.stylePreprocessorOptions.includePaths.forEach((includePath) => includePaths.push(path.resolve(appRoot, includePath))); lessPathOptions = { paths: includePaths, }; } // process global styles if (appConfig.styles.length > 0) { const globalStyles = utils_1.extraEntryParser(appConfig.styles, appRoot, 'styles'); // add style entry points globalStyles.forEach(style => entryPoints[style.entry] ? entryPoints[style.entry].push(style.path) : entryPoints[style.entry] = [style.path]); // add global css paths globalStylePaths.push(...globalStyles.map((style) => style.path)); } // set base rules to derive final rules from const baseRules = [ { test: /\.css$/, use: [] }, { test: /\.scss$|\.sass$/, use: [{ loader: 'sass-loader', options: { sourceMap: cssSourceMap, // bootstrap-sass requires a minimum precision of 8 precision: 8, includePaths } }] }, { test: /\.less$/, use: [{ loader: 'less-loader', options: Object.assign({ sourceMap: cssSourceMap }, lessPathOptions) }] }, { test: /\.styl$/, use: [{ loader: 'stylus-loader', options: { sourceMap: cssSourceMap, paths: includePaths } }] } ]; const commonLoaders = [ { loader: 'css-loader', options: { sourceMap: cssSourceMap, importLoaders: 1 } }, { loader: 'postcss-loader', options: { // A non-function property is required to workaround a webpack option handling bug ident: 'postcss', plugins: postcssPluginCreator, sourceMap: cssSourceMap } } ]; // load component css as raw strings const rules = baseRules.map(({ test, use }) => ({ exclude: globalStylePaths, test, use: [ 'exports-loader?module.exports.toString()', ...commonLoaders, ...use ] })); // load global css as css files if (globalStylePaths.length > 0) { rules.push(...baseRules.map(({ test, use }) => { const extractTextPlugin = { use: [ ...commonLoaders, ...use ], // publicPath needed as a workaround https://github.com/angular/angular-cli/issues/4035 publicPath: '' }; const ret = { include: globalStylePaths, test, use: buildOptions.extractCss ? ExtractTextPlugin.extract(extractTextPlugin) : ['style-loader', ...extractTextPlugin.use] }; // Save the original options as arguments for eject. if (buildOptions.extractCss) { ret[eject_1.pluginArgs] = extractTextPlugin; } return ret; })); } if (buildOptions.extractCss) { // extract global css from js files into own css file extraPlugins.push(new ExtractTextPlugin({ filename: `[name]${hashFormat.extract}.bundle.css` })); // suppress empty .js files in css only entry points extraPlugins.push(new suppress_entry_chunks_webpack_plugin_1.SuppressExtractedTextChunksWebpackPlugin()); } return { entry: entryPoints, module: { rules }, plugins: [].concat(extraPlugins) }; } exports.getStylesConfig = getStylesConfig; //# sourceMappingURL=/users/hansl/sources/hansl/angular-cli/models/webpack-configs/styles.js.map