11const fs = require ( "fs-extra" ) ;
2- const sass = require ( "sass " ) ;
2+ const postcss = require ( "postcss " ) ;
33const util = require ( "util" ) ;
44const tmp = require ( "tmp" ) ;
55const path = require ( "path" ) ;
6- const csstree = require ( "css-tree" ) ;
76
8- const sassRender = util . promisify ( sass . render ) ;
7+ const readFile = util . promisify ( fs . readFile ) ;
98const writeFile = util . promisify ( fs . writeFile ) ;
109const ensureDir = util . promisify ( fs . ensureDir ) ;
1110
12- module . exports = ( options = { } ) => ( {
13- name : "sass " ,
11+ module . exports = ( options = { plugins : [ ] } ) => ( {
12+ name : "postcss " ,
1413 setup : function ( build ) {
1514 const { rootDir = options . rootDir || process . cwd ( ) } = options ;
1615 const tmpDirPath = tmp . dirSync ( ) . name ;
1716 build . onResolve (
18- { filter : / .\. ( s c s s | s a s s ) $ / , namespace : "file" } ,
17+ { filter : / .\. ( c s s ) $ / , namespace : "file" } ,
1918 async ( args ) => {
2019 const sourceFullPath = path . resolve ( args . resolveDir , args . path ) ;
2120 const sourceExt = path . extname ( sourceFullPath ) ;
@@ -27,14 +26,15 @@ module.exports = (options = {}) => ({
2726 const tmpFilePath = path . resolve ( tmpDir , `${ sourceBaseName } .css` ) ;
2827 await ensureDir ( tmpDir ) ;
2928
30- // Compile SASS to CSS
31- let css = ( await sassRender ( { file : sourceFullPath } ) ) . css . toString ( ) ;
29+ const css = await readFile ( sourceFullPath ) ;
3230
33- // Replace all relative urls
34- css = await replaceUrls ( css , tmpFilePath , sourceDir , rootDir ) ;
31+ const result = postcss ( options . plugins ) . process ( css , {
32+ from : sourceFullPath ,
33+ to : tmpFilePath ,
34+ } ) ;
3535
3636 // Write result file
37- await writeFile ( tmpFilePath , css ) ;
37+ await writeFile ( tmpFilePath , result . css ) ;
3838
3939 return {
4040 path : tmpFilePath ,
@@ -43,76 +43,3 @@ module.exports = (options = {}) => ({
4343 ) ;
4444 } ,
4545} ) ;
46-
47- async function replaceUrls ( css , newCssFileName , sourceDir , rootDir ) {
48- const ast = csstree . parse ( css ) ;
49-
50- csstree . walk ( ast , {
51- enter ( node ) {
52- if ( node . type === "Url" ) {
53- const value = node . value ;
54- const stringValue = value . value ;
55-
56- let normalizedUrl ;
57- if ( value . type === "String" ) {
58- const match = stringValue . match ( / ^ [ ' " ] ( .* ) [ " ' ] $ / s) ;
59- if ( match ) {
60- normalizedUrl = match [ 1 ] ;
61- } else {
62- normalizedUrl = stringValue ;
63- }
64- } else {
65- normalizedUrl = stringValue ;
66- }
67-
68- if ( isLocalFileUrl ( normalizedUrl ) ) {
69- const resolved = resolveUrl ( normalizedUrl , sourceDir , rootDir ) ;
70- const relativePath = path . relative ( newCssFileName , resolved . file ) ;
71-
72- node . value = {
73- ...node . value ,
74- type : "String" ,
75- // disable keeping query and hash parts of original url, since esbuild doesn't support it yet
76- // value: `"${relativePath}${resolved.query}${resolved.hash}"`,
77- value : `"${ relativePath } "` ,
78- } ;
79- }
80- }
81- } ,
82- } ) ;
83-
84- return csstree . generate ( ast ) ;
85- }
86-
87- function isLocalFileUrl ( url ) {
88- if ( / ^ h t t p s ? : \/ \/ / i. test ( url ) ) {
89- return false ;
90- }
91- if ( / ^ d a t a : / . test ( url ) ) {
92- return false ;
93- }
94- if ( / ^ # / . test ( url ) ) {
95- return false ;
96- }
97-
98- return true ;
99- }
100-
101- function resolveUrl ( url , originalFolder , rootDir ) {
102- const [ _ , pathname , query , hash ] = url . match ( / ^ ( .* ?) ( \? .* ?) ? ( # .* ?) ? $ / ) ;
103-
104- let file = "" ;
105- if ( pathname . startsWith ( "/" ) ) {
106- file = path . resolve ( rootDir , pathname . substring ( 1 ) ) ;
107- // todo: resolve by root dir
108- } else {
109- file = path . resolve ( originalFolder , pathname ) ;
110- }
111-
112- return {
113- file,
114- pathname,
115- query : query || "" ,
116- hash : hash || "" ,
117- } ;
118- }
0 commit comments