目前来讲模块化已经是Web前端开发的标配了, 主流无非是CommonJS规范和AMD规范
RequireJS
以AMD规范的翘楚 RequireJS 举例,它提供了requirejs-text插件,使得开发者可以异步地引入样式跟模板数据
1 | require(["some/module", "text!some/module.html", "text!some/module.css"], |
这时候我们已经在匿名的回调函数中拿到了html和css的实参字符串,html的模板字符串可以通过innerHTML使用,但是css字符串还需要插入进style才能生效
1 | document.getElementsByTagName("style")[0].innerHTML = css; |
这样一个模块的三个基本要素(模板、样式、脚本)就加载齐全了
SeaJS
SeaJS同样使用插件实现了引入文本文件的功能
`seajs-text`实现了加载模板字符串的功能,
`seajs-css`实现了加载样式表字符串的功能
`seajs-style`能够加载一个css文件,和link标签一样
Browserify如何实现

作为前端CommonJS化的宠儿,目前模块化开发的绝对主流Browserify,配合HTML5的script标签新属性async,可以无阻塞的加载模块
需要注意的是:`async`属性一旦使用,就要考虑好`browserify`打包好的那些模块是否有依赖性,如果有依赖性,建议把这些依赖的模块打包为一个模块,不然async标示过的脚本是不会等待`DomReady`之后再执行的,这样很危险
这里不会介绍Browserify的使用场景以及怎么使用,而是为了解决特定的引入文本文件的功能,这里默认大家已经知晓了它的简单使用,不明请去官网查阅
Browserify使用了transform以及配合transform的相应插件实现了引入模板、样式等等文本文件的功能
transform又是什么?
Transform source code before parsing it for require() calls with the transform function or module name tr
就是说,在解析require调用之前来转换引入的源代码,通过这一层类似于中间件的功能,使得browserify在拓展性上大有可为
注:在项目中我习惯使用CLI,用watchify配合transform插件,来实现实时转化和编译
怎么引入模板文件
我使用过的三个transform插件可以实现:
- stringify
- html2js-browserify
- browserify-compile-templates
(限定了你使用的模板引擎为Underscore Template,把单独模板放到同一html静态文件,中,通过script的ID来分别调用,灵活性欠妥,不推荐) - blissify
(限定了你使用的模板引擎为Biss,不推荐)
stringify和html2js-browserify非常类似,使用API也类似,一起提及
项目使用中:
1 | npm install -S-dev browserify |
或者html2js-browserify
1 | npm install -S-dev browserify |
新建html文件,编写需要使用的模板(以Ejs举例)
../templates/header.html
1 | <header> |
在我们的CommonJS模块里就可以使用了
../modules/header/header.js
1 | var $ = require('jquery'); |
最简单的命令行(使用wacthify附加监视功能)如下:
1 | browserify -t stringify header.js -o header_bundle.js |
或者
1 | browserify -t html2js-browserify header.js -o header_bundle.js |
怎么引入样式文件
- 无预处理器编译的
browserify-css
1 | npm install -S-dev browserify |
app.css:
1 | @import url("modules/foo/index.css"); |
app.js:
1 | var css = require('./app.css'); |
编译时如果添加参数 --autoInject=true,那么你的HTML文件的head标签将被插入style,否则需要你手动插入
1 | watchify -t browserify-css [ --autoInject=true ] app.js > bundle.js |
cssify
这个插件使用的人最多,可能是因为最简单
1 | npm install -S-dev browserify |
style.css:
1 | body { |
app.js:
1 | var styleNode = require('./style.css'); |
编译时默认将require的样式表插入head标签
1 | watchify -t cssify app.js > bundle.js |
- 包含预处理器编译的
以require-stylify为例,node-lessify很类似,但是只能编译less
1 | npm install -S-dev browserify |
app.js
1 | require('./less/main.less'); |
编译后被引入的样式表就会出现在head标签中了,
1 | watchify -t require-stylify app.js > bundle.js |
实际上样式被编译后,生成的css文件直接存在于预处理文件的同目录下
即
./less/main.css
./sass/sassFile.css
总结
以上,个人觉得虽然失去了异步模块的特性,但是作为现代模块工具,Browserify配合script标签的async属性,完全可以适用于生产环境,而且相应灵活性更高,社区的插件更丰富。
感谢阅读