|
1 | 1 | // tooling
|
2 |
| -import mergeSourceMaps from './lib/merge-source-maps'; |
3 |
| -import postcss from 'postcss'; |
4 |
| -import sassResolve from '@csstools/sass-import-resolve'; |
5 |
| -import sass from 'sass'; |
6 |
| -import { dirname, resolve as pathResolve } from 'path'; |
7 |
| - |
8 |
| -// transform css with sass |
9 |
| -export default postcss.plugin('postcss-sass', opts => (root, result) => { |
10 |
| - // postcss configuration |
11 |
| - const postConfig = Object.assign({}, result.opts, requiredPostConfig); |
12 |
| - |
13 |
| - // postcss results |
14 |
| - const { css: postCSS, map: postMap } = root.toResult(postConfig); |
15 |
| - |
16 |
| - // include paths |
17 |
| - const includePaths = [].concat(opts && opts.includePaths || []); |
18 |
| - |
19 |
| - // sass engine to use |
20 |
| - const sassEngine = opts && opts.sass || sass |
21 |
| - |
22 |
| - // sass resolve cache |
23 |
| - const cache = {}; |
24 |
| - |
25 |
| - // replication of the default sass file importer |
26 |
| - const defaultSassImporter = (id, parentId, done) => { |
27 |
| - // resolve the absolute parent |
28 |
| - const parent = pathResolve(parentId); |
29 |
| - |
30 |
| - // cwds is the list of all directories to search |
31 |
| - const cwds = [dirname(parent)].concat(includePaths).map(includePath => pathResolve(includePath)); |
32 |
| - |
33 |
| - cwds.reduce( |
34 |
| - // resolve the first available files |
35 |
| - (promise, cwd) => promise.catch( |
36 |
| - () => sassResolve(id, { cwd, cache, readFile: true }) |
37 |
| - ), |
38 |
| - Promise.reject() |
39 |
| - ).then( |
40 |
| - ({ file, contents }) => { |
41 |
| - // pass the file and contents back to sass |
42 |
| - done({ file, contents }); |
43 |
| - }, |
44 |
| - importerError => { |
45 |
| - // otherwise, pass the error |
46 |
| - done(importerError); |
47 |
| - } |
48 |
| - ); |
49 |
| - } |
50 |
| - |
51 |
| - // sass importer |
52 |
| - const sassImporter = opts && opts.importer || defaultSassImporter |
53 |
| - |
54 |
| - return new Promise( |
55 |
| - // promise sass results |
56 |
| - (resolve, reject) => sassEngine.render( |
57 |
| - // pass options directly into node-sass |
58 |
| - Object.assign({}, opts, requiredSassConfig, { |
59 |
| - file: `${postConfig.from}#sass`, |
60 |
| - outFile: postConfig.from, |
61 |
| - data: postCSS, |
62 |
| - importer(id, parentId, done) { |
63 |
| - const doneWrap = (importerResult) => { |
64 |
| - const file = importerResult && importerResult.file |
65 |
| - if (file) { |
66 |
| - const parent = pathResolve(parentId); |
67 |
| - |
68 |
| - // push the dependency to watch tasks |
69 |
| - result.messages.push({ type: 'dependency', file, parent }); |
70 |
| - } |
71 |
| - |
72 |
| - done(importerResult) |
73 |
| - } |
74 |
| - |
75 |
| - // strip the #sass suffix we added |
76 |
| - const prev = parentId.replace(/#sass$/, '') |
77 |
| - |
78 |
| - // call the sass importer and catch its output |
79 |
| - sassImporter.call(this, id, prev, doneWrap) |
80 |
| - } |
81 |
| - }), |
82 |
| - (sassError, sassResult) => sassError ? reject(sassError) : resolve(sassResult) |
83 |
| - ) |
84 |
| - ).then( |
85 |
| - ({ css: sassCSS, map: sassMap }) => mergeSourceMaps( |
86 |
| - postMap.toJSON(), |
87 |
| - JSON.parse(sassMap) |
88 |
| - ).then(prev => { |
89 |
| - // update root to post-node-sass ast |
90 |
| - result.root = postcss.parse( |
91 |
| - sassCSS.toString(), |
92 |
| - Object.assign({}, postConfig, { |
93 |
| - map: { prev } |
94 |
| - }) |
95 |
| - ); |
96 |
| - }) |
97 |
| - ); |
98 |
| -}); |
| 2 | +import mergeSourceMaps from "./lib/merge-source-maps"; |
| 3 | +// import postcss from 'postcss'; |
| 4 | +import sassResolve from "@csstools/sass-import-resolve"; |
| 5 | +import sass from "sass"; |
| 6 | +import { dirname, resolve as pathResolve } from "path"; |
99 | 7 |
|
100 | 8 | const requiredPostConfig = {
|
101 |
| - map: { |
102 |
| - annotation: false, |
103 |
| - inline: false, |
104 |
| - sourcesContent: true |
105 |
| - } |
| 9 | + map: { |
| 10 | + annotation: false, |
| 11 | + inline: false, |
| 12 | + sourcesContent: true, |
| 13 | + }, |
106 | 14 | };
|
107 | 15 |
|
108 | 16 | const requiredSassConfig = {
|
109 |
| - omitSourceMapUrl: true, |
110 |
| - sourceMap: true, |
111 |
| - sourceMapContents: true |
| 17 | + omitSourceMapUrl: true, |
| 18 | + sourceMap: true, |
| 19 | + sourceMapContents: true, |
| 20 | +}; |
| 21 | + |
| 22 | +// transform css with sass |
| 23 | +const plugin = (opts = {}) => { |
| 24 | + return { |
| 25 | + postcssPlugin: "postcss-sass", |
| 26 | + Once (root, { result, parse }) { |
| 27 | + // postcss configuration |
| 28 | + const postConfig = Object.assign( |
| 29 | + {}, |
| 30 | + result.opts, |
| 31 | + requiredPostConfig |
| 32 | + ); |
| 33 | + |
| 34 | + // postcss results |
| 35 | + const { css: postCSS, map: postMap } = root.toResult(postConfig); |
| 36 | + |
| 37 | + // include paths |
| 38 | + const includePaths = [].concat(opts && opts.includePaths || []); |
| 39 | + |
| 40 | + // sass engine to use |
| 41 | + const sassEngine = opts && opts.sass || sass; |
| 42 | + |
| 43 | + // sass resolve cache |
| 44 | + const cache = {}; |
| 45 | + |
| 46 | + // replication of the default sass file importer |
| 47 | + const defaultSassImporter = (id, parentId, done) => { |
| 48 | + // resolve the absolute parent |
| 49 | + const parent = pathResolve(parentId); |
| 50 | + |
| 51 | + // cwds is the list of all directories to search |
| 52 | + const cwds = [dirname(parent)] |
| 53 | + .concat(includePaths) |
| 54 | + .map((includePath) => pathResolve(includePath)); |
| 55 | + |
| 56 | + cwds.reduce( |
| 57 | + // resolve the first available files |
| 58 | + (promise, cwd) => |
| 59 | + promise.catch(() => |
| 60 | + sassResolve(id, { |
| 61 | + cwd, |
| 62 | + cache, |
| 63 | + readFile: true, |
| 64 | + }) |
| 65 | + ), |
| 66 | + Promise.reject() |
| 67 | + ).then( |
| 68 | + ({ file, contents }) => { |
| 69 | + // pass the file and contents back to sass |
| 70 | + done({ file, contents }); |
| 71 | + }, |
| 72 | + (importerError) => { |
| 73 | + // otherwise, pass the error |
| 74 | + done(importerError); |
| 75 | + } |
| 76 | + ); |
| 77 | + }; |
| 78 | + |
| 79 | + // sass importer |
| 80 | + const sassImporter = opts && opts.importer || defaultSassImporter; |
| 81 | + |
| 82 | + return new Promise( |
| 83 | + // promise sass results |
| 84 | + (resolve, reject) => |
| 85 | + sassEngine.render( |
| 86 | + // pass options directly into node-sass |
| 87 | + Object.assign({}, opts, requiredSassConfig, { |
| 88 | + file: `${postConfig.from}#sass`, |
| 89 | + outFile: postConfig.from, |
| 90 | + data: postCSS, |
| 91 | + importer(id, parentId, done) { |
| 92 | + const doneWrap = (importerResult) => { |
| 93 | + const file = |
| 94 | + importerResult && importerResult.file; |
| 95 | + if (file) { |
| 96 | + const parent = pathResolve(parentId); |
| 97 | + |
| 98 | + // push the dependency to watch tasks |
| 99 | + result.messages.push({ |
| 100 | + type: "dependency", |
| 101 | + file, |
| 102 | + parent, |
| 103 | + }); |
| 104 | + } |
| 105 | + |
| 106 | + done(importerResult); |
| 107 | + }; |
| 108 | + |
| 109 | + // strip the #sass suffix we added |
| 110 | + const prev = parentId.replace(/#sass$/, ""); |
| 111 | + |
| 112 | + // call the sass importer and catch its output |
| 113 | + sassImporter.call(this, id, prev, doneWrap); |
| 114 | + }, |
| 115 | + }), |
| 116 | + (sassError, sassResult) => |
| 117 | + sassError ? reject(sassError) : resolve(sassResult) |
| 118 | + ) |
| 119 | + ).then(({ css: sassCSS, map: sassMap }) => |
| 120 | + mergeSourceMaps(postMap.toJSON(), JSON.parse(sassMap)).then( |
| 121 | + (prev) => { |
| 122 | + // update root to post-node-sass ast |
| 123 | + result.root = parse( |
| 124 | + sassCSS.toString(), |
| 125 | + Object.assign({}, postConfig, { |
| 126 | + map: { prev }, |
| 127 | + }) |
| 128 | + ); |
| 129 | + } |
| 130 | + ) |
| 131 | + ); |
| 132 | + }, |
| 133 | + }; |
112 | 134 | };
|
| 135 | +plugin.postcss = true; |
| 136 | +export default plugin; |
0 commit comments