utils.readFile(filePath).then(css => { var fileInfo = path.parse(filePath); var plugins = [ postcssModules({ generateScopedName: process.env.NODE_ENV === 'production' ? '[hash:base64:5]' : '[path][local]', getJSON: ( cssFileName, json ) => (module = json), }), atImport(), // stylus не поддерживает импорт css файлов url({ url: "rebase" }) ]; stylus(css) .import(path.resolve(config.basePath, 'styles', 'index.styl')) .render(function ( err, css ) { if (err) return reject(err); // console.log(css); postcss(plugins).process(css, { from: filePath, to: path.resolve(config.basePath, 'style.css') }) .then(result => { // console.log(result.css); resolve({ module, css: result.css, name: fileInfo.name }); }, err => { reject(err) }); }); });
const cssModulify = (path, data, map) => { let json = {}; const getJSON = (_, _json) => json = _json; return postcss([postcssModules({getJSON})]).process(data, {from: path, map}).then(x => { const exports = 'module.exports = ' + JSON.stringify(json) + ';'; return { data: x.css, map: x.map, exports }; }); };
const cssModulify = (path, data, map) => { let json = {}; const getJSON = (_, _json) => json = _json; return postcss([postcssModules({getJSON})]).process(data, {from: path, map}).then(x => { console.log("EXPORTS FROM PATH", path, "MAP", map, "X.MAP", x.map, ":", JSON.stringify(json)) const exports = 'module.exports = ' + JSON.stringify(json) + ';'; return { data: x.css, map: x.map, exports }; }); };
gulp.task('css:modules:json', function () { var processors = [ postcss_modules({ generateScopedName: '[name]__[local]__[hash:base64:5]', getJSON: function (cssFileName, json) { var cssName = path.basename(cssFileName, '.css'); var jsonFileName = path.resolve(static_build_json, cssName + '.json'); fs.writeFileSync(jsonFileName, JSON.stringify(json)); } }) ] return gulp.src(static_src + '/css/*.css') .pipe(postcss(processors)) .pipe(gulp.dest(static_build + '/css')) })
gulp.task('sass', () => { const _stubMap = {}; const sassTask = gulp.src('client/src/**/*.scss') .pipe(sass().on('error', sass.logError)) .pipe(postcss([ postcssModules({ getJSON: (cssFilename, json) => { if (cssFilename.match(/\.css$/)) { const stubFilename = cssFilename.replace(/\.css$/, '.scss.ts'); const lines = []; lines.push('/* tslint:disable */'); lines.push(`require('./${path.basename(cssFilename)}');`); lines.push('const styles = {'); lines.push(Object.keys(json).map((className) => { if (className.indexOf('-') >= 0) { return ` '${className}': '${json[className]}'`; } else { return ` ${className}: '${json[className]}'`; } }).join(',\n')); lines.push('};'); lines.push('export default styles;'); _stubMap[cssFilename] = lines.join('\n') + '\n'; } } }) ])); const stubTask = sassTask.pipe(clone()) .pipe(through.obj(function (chunk, enc, callback) { chunk.contents = new Buffer(_stubMap[chunk.path]); chunk.path = chunk.path.replace(/\.css$/, '.scss.ts'); this.push(chunk); callback(); })) .pipe(gulp.dest('client/src')); const destTask = sassTask.pipe(gulp.dest('client/dist')); return es.merge(stubTask, destTask); });
postcss: function() { return [ atImport({ plugins: [easyImport], }), postCssModules({ scopeBehaviour: 'global', generateScopedName: '[name]__[local]___[hash:base64:5]', }), autoprefixer, precss({ variables: { variables: require('./src/styles/vars.css') } }), functions({ functions: require('./src/styles/funcs.css') }) ]; }
const nodeResolve = require('rollup-plugin-node-resolve'); const postcss = require('rollup-plugin-postcss'); const postcssModules = require('postcss-modules'); const precss = require('precss'); const postcssSCSS = require('postcss-scss'); const postcssCalc = require('postcss-calc'); const cssExportMap = {}; const base = [ postcss({ plugins: [ precss(), postcssModules({ getJSON (id, exportTokens) { cssExportMap[id] = exportTokens; } }), postcssCalc({ warnWhenCannotResolve: true }) ], parser: postcssSCSS, getExport (id) { return cssExportMap[id]; } }), string({ include: ['**/*.svg', '**/*.html'] }), nodeResolve({
function visitVariableDeclaration(path, opts, filename) { if ( t.isVariableDeclaration(path.node) && path.node.declarations.length === 1 && path.node.declarations[0].init ) { const {input, tag, match} = getInputAndTag(path.get('declarations')[0].get('init')); if (!match) { return; } const processor = postcss([ modules({ getJSON(cssFileName, json) { aliases[path.node.declarations[0].id.name] = json; }, generateScopedName(name, filename, css) { filename = resolve(filename); if (opts.optimised) { const key = stringHash(filename).toString(36) + '_' + stringHash(name).toString(36); let id; let cache = compressedClassesCache; if (opts.cache) { try { cache = JSON.parse(readFileSync(opts.cache, 'utf8')); } catch (ex) { if (ex.code === 'ENOENT') cache = {maxID: 0}; else throw ex; } } if (key in cache) { id = cache[key]; } else { id = cache.maxID++; cache[key] = id; } if (opts.cache) { writeFileSync(opts.cache, JSON.stringify(cache, null, ' ')); } return '_' + (opts.optimised === true ? id : opts.optimised + '_' + id); } const i = css.indexOf('.' + name); const numLines = css.substr(0, i).split(/[\r\n]/).length; const hash = stringHash(css).toString(36); return `_${ name }_${ hash }_${ numLines }`; }, }), ].concat(postPlugins()), ); const transformedCSS = processor.process(input, { from: filename, to: filename, }).css; if (opts.extractCSS) { cssSources[opts.extractCSS][filename] += transformedCSS; path.remove(); } else { path.replaceWith( t.expressionStatement( t.callExpression( tag, [ t.stringLiteral(transformedCSS), ], ), ), ); } } }
function createComponent({ extensions = ['.css'], development = process.env.NODE_ENV !== 'production', }: { extensions?: Array<string>, development?: boolean } = {}) { return createFileTransformer({ name: manifest.name, version: manifest.version, priority: 1500, async callback({ file, resolve, addChunk, context }) { const extName = path.extname(file.filePath) if (!extensions.includes(extName)) { return null } let moduleMap = null const plugins = [] const fileIsModule = file.meta.specified || file.filePath.endsWith(`.module${extName}`) if (fileIsModule) { plugins.push( postcssModules({ scopeBehaviour: 'local', getJSON(_, map) { moduleMap = map }, }), ) } plugins.push( pluginImportResolver({ resolve, context, addChunk, }), ) const inlineCss = context.config.target === 'browser' && development && file.format === 'js' const cssChunk = getChunk('css', null, file.filePath, [], true, false, file.meta) const processed = await postcss(plugins).process( typeof file.contents === 'string' ? file.contents : file.contents.toString(), { from: file.filePath, map: { inline: inlineCss, annotation: false }, }, ) if (file.format === 'js') { const moduleMapContents = moduleMap ? `module.exports = ${JSON.stringify(moduleMap)}\n` : '' if (inlineCss) { return { contents: `${getDevelopmentContents(processed.css)}\n${moduleMapContents}`, sourceMap: false, } } // was imported from a JS file await addChunk(cssChunk) return { contents: moduleMapContents, sourceMap: false, } } else if (file.format === 'css') { // entry or was imported from a css file return { contents: processed.css, sourceMap: processed.map.toJSON(), } } throw new Error(`Unknown format for css files '${file.format}' encountered in loader-css`) }, }) }
var fs = require('fs'); var postCSS = require('postcss'); var cssModules = require('postcss-modules'); var processor = postCSS([ cssModules({ generateScopedName: '[name]__[local]___[hash:base64:5]' }) ]); processor .process(fs.readFileSync("input.css"), { from: "input.css", to: "output.css" }) .then(function(result) { fs.writeFileSync("output.css", result.css) }).catch(function(error) { throw error; });
getResults() { let map = ''; let source = this.inputFile.getContentsAsString(); let fileName = this.inputFile.getBasename(); let packageName = this.inputFile.getPackageName(); let inputFilePath = this.inputFile.getPathInPackage(); let fullInputFilePath = packageName ? '/packages/' + packageName + '/' + inputFilePath : '/' + inputFilePath; let hash = 'data-v-' + Hash(fullInputFilePath); let js = ''; let styles = []; // Script if (this.parts.script && this.component.script) { let tag = this.component.script; let script = tag.contents; let useBabel = true; jsHash = Hash(script); const maps = [] maps.push(generateSourceMap(inputFilePath, source, script, getLineNumber(source, tag.tagStartIndex))) // Lang if (tag.attribs.lang !== undefined) { let lang = tag.attribs.lang; try { let compile = global.vue.lang[lang]; if (!compile) { throwCompileError({ inputFile: this.inputFile, tag: 'script', charIndex: tag.tagStartIndex, action: 'compiling', lang, message: `Can't find handler for lang ${lang}, did you install it?`, }); } else { //console.log(`Compiling <script> in lang ${lang}...`); let result = compile({ source: script, inputFile: this.inputFile, basePath: tag.basePath, dependencyManager: this.dependencyManager, }); script = result.script; if (result.map) { maps.push(result.map); } useBabel = result.useBabel; } } catch (e) { throwCompileError({ inputFile: this.inputFile, tag: 'script', charIndex: tag.tagStartIndex, action: 'compiling', lang, error: e, showError: true }); } } // Export script = script.replace(jsExportDefaultReg, 'return'); // Babel if(useBabel) { // Babel options this.babelOptions.sourceMap = true; this.babelOptions.filename = this.babelOptions.sourceFileName = tag.basePath; this.babelOptions.sourceMapTarget = this.babelOptions.filename + '.map'; // Babel compilation try { let output = Babel.compile(script, this.babelOptions); script = output.code; if (output.map) { maps.push(output.map); } } catch(e) { let errorOptions = { inputFile: this.inputFile, tag: 'script', charIndex: tag.tagStartIndex, action: 'compiling', message: (e.message?e.message:`An Babel error occured`), error: e, }; if(e.loc) { errorOptions.line = e.loc.line; errorOptions.column = e.loc.column; } else { errorOptions.charIndex = tag.tagStartIndex; if(!e.message) { errorOptions.showError = true; } else { errorOptions.showStack = true; } } throwCompileError(errorOptions); } } const lastMap = maps[maps.length - 1] // Merge source maps try { if (maps.length > 1) { map = SourceMapMerger.createMergedSourceMap(maps, true) } else { map = maps[0] } } catch (e) { console.error(`Error while mergin sourcemaps for ${inputFilePath}`, e.message) console.log(maps) map = maps[0] } if (typeof map === 'string') { map = JSON.parse(map) } map.sourcesContent = [ source ] map.names = lastMap.names map.file = this.inputFile.getPathInPackage() js += '__vue_script__ = (function(){' + script + '\n})();'; } // Template let template; if (this.parts.template && this.component.template) { let templateTag = this.component.template; template = templateTag.contents; // Lang if (templateTag.attribs.lang !== undefined && templateTag.attribs.lang !== "html") { let lang = templateTag.attribs.lang; try { let compile = global.vue.lang[lang]; if (!compile) { throwCompileError({ inputFile: this.inputFile, tag: 'template', charIndex: templateTag.tagStartIndex, action: 'compiling', lang, message: `Can't find handler for lang ${lang}, did you install it?`, }); } else { //console.log(`Compiling <template> in lang ${lang}...`); let result = compile({ source: template, inputFile: this.inputFile, basePath: templateTag.basePath, dependencyManager: this.dependencyManager, }); template = result.template; } } catch (e) { throwCompileError({ inputFile: this.inputFile, tag: 'template', charIndex: templateTag.tagStartIndex, action: 'compiling', lang, error: e, showError: true }); } } // Tag hash (for scoping) if (vueVersion === 1) { template = template.replace(tagReg, (match, p1, p2, offset) => { let attributes = p2; if (!attributes) { return match.replace(p1, p1 + ` ${hash}`); } else { attributes += ` ${hash}`; return match.replace(p2, attributes); } }); } } // Styles let cssModules; if(this.parts.style) { for (let styleTag of this.component.styles) { let css = styleTag.contents; let cssMap = null; // Lang if (styleTag.attribs.lang !== undefined && styleTag.attribs.lang !== 'css') { let lang = styleTag.attribs.lang; try { let compile = global.vue.lang[lang]; if (!compile) { throwCompileError({ inputFile: this.inputFile, tag: 'style', charIndex: styleTag.tagStartIndex, action: 'compiling', lang, message: `Can't find handler for lang ${lang}, did you install it?`, }); } else { //console.log(`Compiling <style> in lang ${lang}...`); let result = compile({ source: css, inputFile: this.inputFile, basePath: styleTag.basePath, dependencyManager: this.dependencyManager, }); //console.log('Css result', result); css = result.css; cssMap = result.map; } } catch (e) { throwCompileError({ inputFile: this.inputFile, tag: 'style', charIndex: styleTag.tagStartIndex, action: 'compiling', lang, error: e, showError: true }); } } // Postcss let plugins = []; let postcssOptions = { from: inputFilePath, to: inputFilePath, map: { inline: false, annotation: false, prev: cssMap } } // Scoped if (styleTag.attribs.scoped) { plugins.push(scopeId({ id: hash })); } // CSS Modules let isAsync = false; let defaultModuleName = '$style'; if (styleTag.attribs.module) { if (global.vue.cssModules) { try { let compile = global.vue.cssModules; //console.log(`Compiling <style> css modules ${lang}...`); let result = compile({ source: css, map: cssMap, inputFile: this.inputFile, dependencyManager: this.dependencyManager, tag: styleTag, }); // console.log('Css result', result); css = result.css; cssMap = result.map; if (result.cssModules) { const moduleName = typeof styleTag.attribs.module === 'string' ? styleTag.attribs.module : defaultModuleName; if (cssModules === undefined) { cssModules = {}; } cssModules[moduleName] = { ...(cssModules[moduleName] || {}), ...result.cssModules }; } if (result.js) { js += result.js; } } catch (e) { throwCompileError({ inputFile: this.inputFile, tag: 'style', charIndex: styleTag.tagStartIndex, action: 'compiling css modules', error: e, showError: true }); } } else { const moduleName = typeof styleTag.attribs.module === 'string' ? styleTag.attribs.module : defaultModuleName; const scopedModuleName = moduleName !== defaultModuleName ? `__${moduleName}` : ''; plugins.push(postcssModules({ getJSON(cssFilename, json) { if (cssModules === undefined) cssModules = {}; cssModules[moduleName] = { ...(cssModules[moduleName] || {}), ...json }; }, generateScopedName(exportedName, filePath) { const path = require('path'); let sanitisedPath = path.relative(process.cwd(), filePath).replace(/.*\{}[/\\]/, '').replace(/.*\{.*?}/, 'packages').replace(/\.[^\.\/\\]+$/, '').replace(/[\W_]+/g, '_'); const filename = path.basename(filePath).replace(/\.[^\.\/\\]+$/, '').replace(/[\W_]+/g, '_'); sanitisedPath = sanitisedPath.replace(new RegExp(`_(${filename})$`), '__$1'); return `_${sanitisedPath}${scopedModuleName}__${exportedName}`; }, })); isAsync = true; } } // Autoprefixer if (styleTag.attribs.autoprefix !== 'off') { plugins.push(autoprefixer()); } // Postcss result let result; if (isAsync) { result = Promise.await(postcss(plugins).process(css, postcssOptions)); } else { result = postcss(plugins).process(css, postcssOptions); } css = result.css; cssMap = result.map; styles.push({ css, map: cssMap }) } } let compileResult = { code: js, map, styles, template, cssModules, hash, }; //console.log('Result', compileResult); return compileResult; }
rename = require('gulp-rename'), gutil = require('gulp-util'), minifyImg = require('gulp-imagemin'), pngquant = require('imagemin-pngquant'), sprite = require('gulp.spritesmith-multi'), hash = require('hash-file'), less = require('gulp-less'), postcss = require('gulp-postcss'), cssAutoprefixer = require('autoprefixer'), cssmodules = require('postcss-modules'), cssPlugins = [cssAutoprefixer(), cssmodules({ getJSON: function(cssFileName, json) { var basename = path.basename(cssFileName, '.css'), dirname = path.dirname(cssFileName), cssmap = path.join(dirname, basename + '.css.map.js'); if(Object.keys(json).length == 0) return; fs.writeFileSync(cssmap, 'export default ' + JSON.stringify(json)); } })], jspmCfg = 'config.js', mockDir = 'mock', distDir = 'dist', libJs = 'module/lib.js', uiName = 'kfui', uiModPath = 'src/module', uiPath = 'jspm_packages/github/shikuijie/'; mockJs = path.join(mockDir, '/**/*.js');
export default function (opts = {}) { const mode = opts.mode || "insert"; const modules = !!opts.modules; const isCssFile = opts.filter || /\.css$/; const processor = postcss(opts.plugins || []); let moduleClassnameMaps = null; if (modules) { moduleClassnameMaps = {}; processor.use(postcssModules({ getJSON (modulePath, json) { moduleClassnameMaps[modulePath] = json; } })); } checkMode(mode); return (override, transform) => { /** * Modules whose file paths match the provided filter (`.css` by default) * should be of type `css`. */ transform("setModuleType", module => { return isCssFile.test(module.path) ? assign({}, module, { type: "css" }) : module; }); /** * Modules of type `css` should be parsed with PostCSS. */ override("parseModule", module => { if (module.type !== "css") { return override.CONTINUE; } return assign({}, module, { ast: postcss.parse(module.rawSource, { from: module.path }) }); }); /** * CSS is transformed via a PostCSS processor. This processor is * configured when the plugin is initialized, using the plugins that * were provided. */ override("transformModule", module => { if (module.type !== "css") { return override.CONTINUE; } return processor.process(module.ast).then(result => { return assign({}, module, { ast: result.root, synchronousRequires: [] }); }); }); /** * No extra work needs to occur here. CSS modules should have no * run-time dependencies. */ override("updateRequires", module => { if (module.type !== "css") { return override.CONTINUE; } return module; }); /** * Bundles should be of type `css` if their module entry point is a CSS * module. */ override("initBundle", bundleOpts => { if (!bundleOpts.module || bundleOpts.module.type !== "css") { return override.CONTINUE; } return assign({}, bundleOpts, { type: "css" }); }); transform("generateBundles", function (bundles, [, moduleMaps]) { // Return a JavaScript object with selectors as keys and rulesets as // values. These rulesets will be expressed as objects with rule names // as keys and rule values as values. if (mode === "object") { return generateRuleSetObj(bundles); } // Output a .css file for per-bundle CSS modules. If in CSS module // mode, instead return a mapping of original and mapped class names. if (mode === "bundle") { return generateCssBundles.call(this, bundles, moduleClassnameMaps); } // Transforms CSS modules into separate distinct CSS output bundles, and // replaces with a JavaScript module. When required, this module will // insert a <script> tag into the DOM, referencing the CSS output bundle. if (mode === "tag") { // TODO } // Transform CSS into JS that inserts the rules, and return the DOM element. if (mode === "insert") { return generateStyleLoaders(bundles, values(moduleMaps.byHash), moduleClassnameMaps); } return bundles; }); /** * CSS modules that are to be emitted as part of a CSS bundle should not * be included in the URL hash used for loading JS modules. */ transform("getUrls", urls => { return chain(urls) .map((url, moduleId) => [moduleId, url]) .filter(([, url]) => !isCssFile.test(url)) .fromPairs() .value(); }); /** * No extra work needs to occur here. */ override("constructBundle", bundle => { // `css-stats` bundles may be emitted when CSS modules output is enabled // and in `bundle` mode. if (bundle.type !== "css" || bundle.type !== "css-stats") { return override.CONTINUE; } return bundle; }); /** * For any bundles of type `css`, convert the PostCSS ASTs of constituent * CSS modules to their string form and concatenate. */ override("generateRawBundles", bundle => { // `css-stats` bundles may be emitted when CSS modules output is enabled // and in `bundle` mode. if (bundle.type === "css-stats") { return bundle; } else if (bundle.type !== "css") { return override.CONTINUE; } return assign({}, bundle, { raw: bundle.modules.map(module => module.ast.toString()).join("\n") }); }); }; }