Skip to content

Commit e05b44c

Browse files
feat(index): support posthtml.config.js && result.messages
1 parent 7bd5896 commit e05b44c

3 files changed

Lines changed: 187 additions & 45 deletions

File tree

‎lib/Error.js‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
classLoaderErrorextendsError{
2+
constructor(err){
3+
super(err);
4+
5+
this.name='PostHTML Loader';
6+
this.message=`\n\n${err.message}\n`;
7+
8+
// TODO(michael-ciniawsky)
9+
// add 'SyntaxError', 'PluginError', 'PluginWarning'
10+
11+
Error.captureStackTrace(this,this.constructor);
12+
}
13+
}
14+
15+
module.exports=LoaderError;

‎lib/index.js‎

Lines changed: 150 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -1,58 +1,163 @@
1+
'use strict'
2+
3+
constpath=require('path')
4+
15
constloaderUtils=require('loader-utils')
6+
constvalidateOptions=require('schema-utils')
7+
8+
constschema=require('./options.json')
9+
210
constposthtml=require('posthtml')
11+
constposthtmlrc=require('posthtml-load-config')
312

4-
module.exports=function(source){
5-
if(this.cacheable)this.cacheable()
13+
constparseOptions=require('./options')
614

7-
// configure options
8-
constqs=loaderUtils.parseQuery(this.query)
15+
constLoaderError=require('./Error')
16+
/**
17+
* PostHTML Loader
18+
*
19+
* @author Michael Ciniawsky <michael.ciniawsky@gmail.com> (@michael-ciniawsky)
20+
* @license MIT
21+
*
22+
* @version 1.0.0
23+
*
24+
* @requires loader-utils
25+
* @requires schema-utils
26+
*
27+
* @requires posthtml
28+
* @requires posthtml-load-config
29+
*
30+
* @method posthtml-loader
31+
*
32+
* @param {String} html HTML
33+
*
34+
* @return {String} html HTML
35+
*/
36+
module.exports=functionloader(html,map,meta){
37+
// Loader Options
38+
constoptions=loaderUtils.getOptions(this)||{}
39+
40+
validateOptions(schema,options,'PostHTML Loader')
41+
42+
// Make the loader async
943
constcb=this.async()
10-
letconfig
11-
try{
12-
config=parseOptions.call(this,this.options.posthtml,qs)
13-
}catch(err){
14-
returncb(err)
15-
}
16-
17-
// configure custom parser argument if necessary
18-
constprocessArgs=[source.toString()]
19-
if(config.parser){processArgs.push({parser: config.parser})}
20-
21-
// run posthtml
22-
constph=posthtml(config.plugins)
23-
ph.process.apply(ph,processArgs)
24-
.then((result)=>cb(null,result.html),cb)
25-
}
44+
constfile=this.resourcePath
2645

27-
functionparseOptions(config=[],qs={}){
28-
constres={}
46+
Promise.resolve().then(()=>{
47+
constlength=Object.keys(options)
48+
.filter((option)=>{
49+
switch(option){
50+
case'ident':
51+
case'config':
52+
return
53+
default:
54+
returnoption
55+
}
56+
})
57+
.length
2958

30-
// if we have a function, run it
31-
if(typeofconfig==='function'){config=config.call(this,this)}
59+
if(length){
60+
returnparseOptions.call(this,options)
61+
}
3262

33-
// if it's not an object at this point, error
34-
if(typeofconfig!=='object'){
35-
thrownewError('Configuration must return an array or object')
36-
}
63+
constrc={
64+
path: path.dirname(file),
65+
ctx: {
66+
file: {
67+
extname: path.extname(file),
68+
dirname: path.dirname(file),
69+
basename: path.basename(file)
70+
},
71+
options: {}
72+
}
73+
}
3774

38-
// if we now have an array, that represents the plugins directly
39-
if(Array.isArray(config)){
40-
res.plugins=config
41-
// if not, it's an object. if a plugin pack is being used, use it.
42-
// otherwise, use default plugins
43-
}else{
44-
res.plugins=qs.pack ? config[qs.pack] : config.plugins
45-
}
75+
if(options.config){
76+
if(options.config.path){
77+
rc.path=path.resolve(options.config.path)
78+
}
4679

47-
// load in the custom parser if there is one
48-
if(config.parser){res.parser=config.parser}
80+
if(options.config.ctx){
81+
rc.ctx.options=options.config.ctx
82+
}
83+
}
4984

50-
// try loading custom parser from query
51-
if(qs.parser){
52-
res.parser=require(qs.parser)
53-
}
85+
returnposthtmlrc(rc.ctx,rc.path,{argv: false})
86+
})
87+
.then((config)=>{
88+
if(!config)config={}
5489

55-
returnres
56-
}
90+
if(config.file)this.addDependency(config.file)
91+
92+
if(config.options){
93+
// Disable overriding `options.to` (`posthtml.config.js`)
94+
if(config.options.to)deleteconfig.options.to
95+
// Disable overriding `options.from` (`posthtml.config.js`)
96+
if(config.options.from)deleteconfig.options.from
97+
}
98+
99+
letplugins=config.plugins||[]
100+
letoptions=Object.assign(
101+
{from: file,to: file},
102+
config.options
103+
)
104+
105+
if(typeofoptions.parser==='string'){
106+
options.parser=require(options.parser)()
107+
}
108+
109+
// TODO(michael-ciniawsky) enable if when custom renderer available
110+
// if (typeof options.render === 'string') {
111+
// options.render = require(options.render)()
112+
// }
113+
114+
returnposthtml(plugins)
115+
.process(html,options)
116+
.then((result)=>{
117+
if(result.messages){
118+
result.messages.forEach((msg)=>{
119+
switch(msg.type){
120+
case'error':
121+
this.emitError(msg.message)
57122

58-
module.exports.parseOptions=parseOptions
123+
break
124+
case'warning':
125+
this.emitWarning(msg.message)
126+
127+
break
128+
case'dependency':
129+
this.addDependency(msg.file)
130+
131+
break
132+
default:
133+
break
134+
}
135+
})
136+
}
137+
138+
html=result.html
139+
140+
if(this.loaderIndex===0){
141+
html=`export default \`${html}\``
142+
143+
cb(null,html)
144+
145+
returnnull
146+
}
147+
148+
if(!meta)meta={}
149+
150+
meta.ast={type: 'posthtml',root: result.tree}
151+
meta.messages=result.messages
152+
153+
cb(null,html,map,meta)
154+
155+
returnnull
156+
})
157+
})
158+
.catch((err)=>{
159+
cb(newLoaderError(err))
160+
161+
returnnull
162+
})
163+
}

‎lib/options.js‎

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
'use strict'
2+
3+
module.exports=functionparseOptions(params){
4+
if(typeofparams.plugins==='function'){
5+
params.plugins=params.plugins.call(this,this)
6+
}
7+
8+
letplugins
9+
10+
if(typeofparams.plugins==='undefined')plugins=[]
11+
elseif(Array.isArray(params.plugins))plugins=params.plugins
12+
elseplugins=[params.plugins]
13+
14+
constoptions={}
15+
16+
if(typeofparams!=='undefined'){
17+
options.parser=params.parser
18+
// options.render = params.render
19+
}
20+
21+
returnPromise.resolve({options: options,plugins: plugins})
22+
}

0 commit comments

Comments
 (0)