├── test ├── src │ ├── less │ │ ├── index.less │ │ ├── other2.less │ │ └── other.less │ ├── scss │ │ └── test.scss │ ├── image │ │ └── 1.jpg │ ├── component │ │ ├── jade.vue │ │ ├── a.vue │ │ ├── c.vue │ │ ├── b.vue │ │ └── index.vue │ ├── html │ │ └── index.html │ └── js │ │ ├── page │ │ └── index.js │ │ └── engine │ │ └── mod.js ├── package.json └── fis-conf.js ├── test2 ├── src │ ├── less │ │ ├── index.less │ │ ├── other2.less │ │ └── other.less │ ├── scss │ │ └── test.scss │ ├── image │ │ └── 1.jpg │ ├── component │ │ ├── test-td.vue │ │ ├── jade.vue │ │ ├── test-table.vue │ │ ├── test-bug.vue │ │ ├── a.vue │ │ ├── c.vue │ │ ├── b.vue │ │ └── index.vue │ ├── js │ │ ├── page │ │ │ └── index.js │ │ └── engine │ │ │ └── mod.js │ └── html │ │ └── index.html ├── package.json └── fis-conf.js ├── .gitignore ├── lib ├── replace-scoped-flag.js ├── insert-css.js ├── gen-id.js ├── template-compiler.js └── style-rewriter.js ├── .htmlhintrc ├── .eslintrc ├── package.json ├── index.js └── README.md /test/src/less/index.less: -------------------------------------------------------------------------------- 1 | .index { 2 | // 3 | } 4 | -------------------------------------------------------------------------------- /test/src/less/other2.less: -------------------------------------------------------------------------------- 1 | .other { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /test2/src/less/index.less: -------------------------------------------------------------------------------- 1 | .index { 2 | // 3 | } 4 | -------------------------------------------------------------------------------- /test2/src/less/other2.less: -------------------------------------------------------------------------------- 1 | .other { 2 | 3 | } 4 | -------------------------------------------------------------------------------- /test/src/less/other.less: -------------------------------------------------------------------------------- 1 | .other { 2 | width: 100px; 3 | } 4 | -------------------------------------------------------------------------------- /test2/src/less/other.less: -------------------------------------------------------------------------------- 1 | .other { 2 | width: 100px; 3 | } 4 | -------------------------------------------------------------------------------- /test/src/scss/test.scss: -------------------------------------------------------------------------------- 1 | body { 2 | .test-scss { 3 | width: auto; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test2/src/scss/test.scss: -------------------------------------------------------------------------------- 1 | body { 2 | .test-scss { 3 | width: auto; 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/src/image/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccqgithub/fis3-parser-vue-component/HEAD/test/src/image/1.jpg -------------------------------------------------------------------------------- /test2/src/image/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ccqgithub/fis3-parser-vue-component/HEAD/test2/src/image/1.jpg -------------------------------------------------------------------------------- /test2/src/component/test-td.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 9 | 10 | 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.log 2 | *.pid 3 | *.seed 4 | .DS_Store 5 | .grunt 6 | .npm 7 | .tag* 8 | 9 | npm-debug.log* 10 | package-lock.json 11 | 12 | node_modules 13 | **/node_modules 14 | 15 | /test/output 16 | /test2/output 17 | -------------------------------------------------------------------------------- /test2/src/js/page/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | import Index from '../../component/index'; 4 | 5 | var app = new (Vue.extend(Index))().$mount(); 6 | document.getElementById('app').appendChild(app.$el) 7 | 8 | 9 | /** 10 | * @require '../../less/index.less' 11 | */ 12 | -------------------------------------------------------------------------------- /lib/replace-scoped-flag.js: -------------------------------------------------------------------------------- 1 | module.exports = function(str, cssScopedFlag, vuecId) { 2 | var reg = new RegExp('([^a-zA-Z0-9\-_])('+ cssScopedFlag +')([^a-zA-Z0-9\-_])', 'g'); 3 | str = str.replace(reg, function($0, $1, $2, $3) { 4 | return $1 + vuecId + $3; 5 | }); 6 | return str; 7 | } 8 | -------------------------------------------------------------------------------- /test/src/component/jade.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /test2/src/component/jade.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 14 | -------------------------------------------------------------------------------- /test2/src/component/test-table.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | 17 | 19 | -------------------------------------------------------------------------------- /.htmlhintrc: -------------------------------------------------------------------------------- 1 | { 2 | "tagname-lowercase": false, 3 | "attr-lowercase": true, 4 | "attr-value-double-quotes": true, 5 | "doctype-first": true, 6 | "tag-pair": true, 7 | "spec-char-escape": true, 8 | "id-unique": true, 9 | "src-not-empty": true, 10 | "attr-no-duplication": true, 11 | "title-require": true 12 | } 13 | -------------------------------------------------------------------------------- /test2/src/component/test-bug.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 20 | -------------------------------------------------------------------------------- /test/src/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fis3-parser-vue-component demo 6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test2/src/html/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | fis3-parser-vue-component demo 6 | 7 | 8 |
9 | 10 |
11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/src/js/page/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue'; 2 | 3 | import Index from '../../component/index'; 4 | 5 | var app = new Vue({ 6 | el: '#app', 7 | methods: { 8 | 9 | }, 10 | components: { 11 | Index: Index, 12 | App: require('../../component/index').default 13 | }, 14 | created() { 15 | console.log('created'); 16 | } 17 | }); 18 | 19 | /** 20 | * @require '../../less/index.less' 21 | */ 22 | -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "globals": { 3 | 4 | }, 5 | "parserOptions": { 6 | "ecmaVersion": 6, 7 | "sourceType": "module", 8 | "ecmaFeatures": { 9 | "jsx": true 10 | } 11 | }, 12 | "rules": { 13 | "strict": [0], 14 | "quotes": [0], 15 | "generator-star-spacing": [0] 16 | }, 17 | "env": { 18 | "browser": true, 19 | "node": true, 20 | "commonjs": true, 21 | "es6": true 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /lib/insert-css.js: -------------------------------------------------------------------------------- 1 | var uglifyJS = require('uglify-js'); 2 | 3 | function insertCSS(styleContent) { 4 | var styleNode = document.createElement("style"); 5 | styleNode.setAttribute("type", "text/css"); 6 | if (styleNode.styleSheet) { 7 | styleNode.styleSheet.cssText = styleContent; 8 | } else { 9 | styleNode.appendChild(document.createTextNode(styleContent)); 10 | } 11 | document.getElementsByTagName("head")[0].appendChild(styleNode); 12 | }; 13 | 14 | module.exports = uglifyJS.minify(insertCSS.toString(), {fromString: true}).code; 15 | -------------------------------------------------------------------------------- /test/src/component/a.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 31 | -------------------------------------------------------------------------------- /test2/src/component/a.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | 18 | 31 | -------------------------------------------------------------------------------- /test/src/component/c.vue: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 21 | 22 | 32 | -------------------------------------------------------------------------------- /test2/src/component/c.vue: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 22 | 23 | 33 | -------------------------------------------------------------------------------- /test/src/component/b.vue: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 21 | 22 | 34 | -------------------------------------------------------------------------------- /test2/src/component/b.vue: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 21 | 22 | 34 | -------------------------------------------------------------------------------- /lib/gen-id.js: -------------------------------------------------------------------------------- 1 | // utility for generating a uid for each component file 2 | // used in scoped CSS rewriting 3 | var hash = require('hash-sum') 4 | var cache = Object.create(null) 5 | 6 | // module.exports = function genId (file) { 7 | // return cache[file] || (cache[file] = hash(file)) 8 | // } 9 | 10 | module.exports = function genId(file, configs){ 11 | if(cache[file.subpath]){ 12 | return cache[file.subpath]; 13 | } 14 | 15 | var scopeId; 16 | 17 | // scope replace 18 | if (configs.cssScopedType == 'sum') { 19 | scopeId = hash(file.subpath); 20 | } else { 21 | scopeId = fis.util.md5(file.subpath, configs.cssScopedHashLength); 22 | } 23 | 24 | return cache[file.subpath] = scopeId; 25 | }; 26 | -------------------------------------------------------------------------------- /lib/template-compiler.js: -------------------------------------------------------------------------------- 1 | var chalk = require('chalk') 2 | var vueCompiler = require('vue-template-compiler') 3 | var transpile = require('vue-template-es2015-compiler') 4 | 5 | module.exports = function compileTemplate (template) { 6 | var compiled = vueCompiler.compile(template) 7 | if (compiled.errors.length) { 8 | compiled.errors.forEach(function (msg) { 9 | console.error('\n' + chalk.red(msg) + '\n') 10 | }) 11 | throw new Error('Vue template compilation failed') 12 | } else { 13 | return { 14 | render: toFunction(compiled.render), 15 | staticRenderFns: '[' + compiled.staticRenderFns.map(toFunction).join(',') + ']' 16 | } 17 | } 18 | } 19 | 20 | function toFunction (code) { 21 | return transpile('function render () {' + code + '}') 22 | } 23 | -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fis3-parser-vue-component-test", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "fis-conf.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "vue": "^1.0.25" 13 | }, 14 | "devDependencies": { 15 | "babel-preset-es2015-loose": "^7.0.0", 16 | "babel-preset-react": "^6.5.0", 17 | "fis-parser-babel-6.x": "^1.0.0", 18 | "fis-parser-jade": "0.0.12", 19 | "fis3-hook-commonjs": "^0.1.22", 20 | "fis3-hook-node_modules": "^2.2.3", 21 | "fis3-parser-less-2.x": "^0.1.4", 22 | "fis-parser-node-sass": "^1.0.1", 23 | "fis3-parser-translate-es3ify": "0.0.2", 24 | "fis3-parser-vue-component": "^1.2.1", 25 | "fis3-postpackager-loader": "^1.5.2", 26 | "fis3-postprocessor-autoprefixer": "^1.0.0" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /test2/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fis3-parser-vue-component-test", 3 | "version": "1.0.0", 4 | "description": "", 5 | "main": "fis-conf.js", 6 | "scripts": { 7 | "test": "echo \"Error: no test specified\" && exit 1" 8 | }, 9 | "author": "", 10 | "license": "ISC", 11 | "dependencies": { 12 | "vue": "^2.5.2" 13 | }, 14 | "devDependencies": { 15 | "babel-preset-es2015-loose": "^7.0.0", 16 | "babel-preset-es2015-nostrict": "^6.6.2", 17 | "babel-preset-es2015-without-strict": "0.0.4", 18 | "babel-preset-react": "^6.5.0", 19 | "fis-parser-babel-6.x": "^1.0.0", 20 | "fis-parser-jade": "0.0.12", 21 | "fis-parser-node-sass": "^1.0.1", 22 | "fis3-hook-commonjs": "^0.1.22", 23 | "fis3-hook-node_modules": "^2.2.3", 24 | "fis3-parser-less-2.x": "^0.1.4", 25 | "fis3-parser-translate-es3ify": "0.0.2", 26 | "fis3-parser-vue-component": "^1.2.1", 27 | "fis3-postpackager-loader": "^1.5.2", 28 | "fis3-postprocessor-autoprefixer": "^1.0.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "fis3-parser-vue-component", 3 | "version": "5.5.1", 4 | "description": "A parser plugin for fis3 to parser vue component.", 5 | "keywords": [ 6 | "fis3", 7 | "fis3-parser-vue-component", 8 | "fis3-parser", 9 | "vue", 10 | "component" 11 | ], 12 | "main": "index.js", 13 | "dependencies": { 14 | "chalk": "^1.1.3", 15 | "deasync": "^0.1.11", 16 | "hash-sum": "^1.0.2", 17 | "lru-cache": "^4.0.2", 18 | "object-assign": "^4.1.0", 19 | "postcss": "^5.2.16", 20 | "postcss-selector-parser": "^2.2.3", 21 | "uglify-js": "^2.8.14", 22 | "vue-template-compiler": "^2.5.2", 23 | "vue-template-es2015-compiler": "^1.6.0" 24 | }, 25 | "devDependencies": {}, 26 | "scripts": { 27 | "test": "node test.js" 28 | }, 29 | "repository": { 30 | "type": "git", 31 | "url": "git+https://github.com/ccqgithub/fis3-parser-vue-component.git" 32 | }, 33 | "author": "Season Chen", 34 | "license": "MIT", 35 | "bugs": { 36 | "url": "https://github.com/ccqgithub/fis3-parser-vue-component/issues" 37 | }, 38 | "homepage": "https://github.com/ccqgithub/fis3-parser-vue-component#readme" 39 | } 40 | -------------------------------------------------------------------------------- /test/src/component/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 22 | 24 | 25 | 34 | 35 | 57 | -------------------------------------------------------------------------------- /test2/src/component/index.vue: -------------------------------------------------------------------------------- 1 | 2 | 16 | 17 | 25 | 27 | 28 | 41 | 42 | 66 | -------------------------------------------------------------------------------- /test/fis-conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var parserVuePlugin = require('../index'); 3 | 4 | // 需要构建的文件 5 | fis.set('project.fileType.text', 'vue'); 6 | fis.set('project.files', ['src/**']); 7 | fis.set('project.ignore', fis.get('project.ignore').concat(['output/**', 'DS_store'])); 8 | 9 | // 模块化支持插件 10 | // https://github.com/fex-team/fis3-hook-commonjs (forwardDeclaration: true) 11 | fis.hook('commonjs', { 12 | extList: [ 13 | '.js', '.coffee', '.es6', '.jsx', '.vue', 14 | ], 15 | umd2commonjs: true, 16 | ignoreDependencies: [ 17 | 18 | ] 19 | }); 20 | 21 | // 禁用components,启用node_modules 22 | fis.unhook('components'); 23 | fis.hook('node_modules'); 24 | 25 | // 所有js文件 26 | fis.match('**.js', { 27 | isMod: true, 28 | rExt: 'js', 29 | useSameNameRequire: true 30 | }); 31 | 32 | // 编译vue组件 33 | fis.match('src/**.vue', { 34 | isMod: true, 35 | rExt: 'js', 36 | useSameNameRequire: true, 37 | parser: [ 38 | parserVuePlugin, 39 | ] 40 | }); 41 | 42 | fis.match('src/**.vue:js', { 43 | isMod: true, 44 | rExt: 'js', 45 | useSameNameRequire: true, 46 | parser: [ 47 | fis.plugin('babel-6.x', { 48 | presets: ['es2015-loose', 'react', 'stage-3'] 49 | }), 50 | fis.plugin('translate-es3ify', null, 'append') 51 | ] 52 | }); 53 | 54 | fis.match('src/**.vue:jade', { 55 | parser: [ 56 | fis.plugin('jade', { 57 | // 58 | }) 59 | ] 60 | }) 61 | 62 | fis.match('src/{**.vue:less,**.less}', { 63 | rExt: 'css', 64 | parser: [fis.plugin('less-2.x')], 65 | postprocessor: fis.plugin('autoprefixer') 66 | }); 67 | 68 | fis.match('src/{**.vue:scss,**.scss}', { 69 | rExt: 'css', 70 | parser: [fis.plugin('node-sass')], 71 | postprocessor: fis.plugin('autoprefixer'), 72 | }); 73 | 74 | // 发布 75 | fis.match('/src/(**)', { 76 | release: '$1' 77 | }); 78 | 79 | // 80 | fis.match('src/(component/**.css)', { 81 | release: 'static/$1' 82 | }); 83 | 84 | // 模块文件 85 | fis.match('/src/**.js', { 86 | parser: [ 87 | fis.plugin('babel-6.x', { 88 | presets: ['es2015-loose', 'react', 'stage-3'] 89 | }), 90 | fis.plugin('translate-es3ify', null, 'append') 91 | ] 92 | }); 93 | 94 | // 非模块文件 95 | fis.match('/src/js/engine/**.js', { 96 | parser: null, 97 | isMod: false 98 | }); 99 | 100 | // 页面直接引入的文件,不进行模块require包装 101 | fis.match('/src/js/page/**.js', { 102 | isMod: false 103 | }); 104 | 105 | // 打包 106 | fis.match('::package', { 107 | postpackager: fis.plugin('loader'), 108 | }); 109 | 110 | // 部署 111 | fis 112 | .media('local') 113 | .match('**', { 114 | deploy: fis.plugin('local-deliver', { 115 | to: path.join(__dirname, './output/') 116 | }) 117 | }); 118 | -------------------------------------------------------------------------------- /lib/style-rewriter.js: -------------------------------------------------------------------------------- 1 | var postcss = require('postcss') 2 | var selectorParser = require('postcss-selector-parser') 3 | var cache = require('lru-cache')(100) 4 | var assign = require('object-assign') 5 | 6 | var deasync = require('deasync') 7 | 8 | var currentId 9 | var addId = postcss.plugin('add-id', function () { 10 | return function (root) { 11 | root.each(function rewriteSelector (node) { 12 | if (!node.selector) { 13 | // handle media queries 14 | if (node.type === 'atrule' && node.name === 'media') { 15 | node.each(rewriteSelector) 16 | } 17 | return 18 | } 19 | node.selector = selectorParser(function (selectors) { 20 | selectors.each(function (selector) { 21 | var node = null 22 | selector.each(function (n) { 23 | if (n.type !== 'pseudo') node = n 24 | }) 25 | selector.insertAfter(node, selectorParser.attribute({ 26 | attribute: currentId 27 | })) 28 | }) 29 | }).process(node.selector).result 30 | }) 31 | } 32 | }) 33 | 34 | /** 35 | * Add attribute selector to css 36 | * 37 | * @param {String} id 38 | * @param {String} css 39 | * @param {Boolean} scoped 40 | * @param {Object} options 41 | * @return {Promise} 42 | */ 43 | 44 | module.exports = deasync(function (id, css, scoped, options, cbk) { 45 | var key = id + '!!' + scoped + '!!' + css 46 | var val = cache.get(key) 47 | if (val) { 48 | cbk(null, val) 49 | } else { 50 | var plugins = [] 51 | var opts = {} 52 | 53 | // // do not support post plugins here, use fis3 style plugins 54 | // if (options.postcss instanceof Array) { 55 | // plugins = options.postcss.slice() 56 | // } else if (options.postcss instanceof Object) { 57 | // plugins = options.postcss.plugins || [] 58 | // opts = options.postcss.options 59 | // } 60 | 61 | // scoped css rewrite 62 | // make sure the addId plugin is only pushed once 63 | if (scoped && plugins.indexOf(addId) === -1) { 64 | plugins.push(addId) 65 | } 66 | 67 | // remove the addId plugin if the style block is not scoped 68 | if (!scoped && plugins.indexOf(addId) !== -1) { 69 | plugins.splice(plugins.indexOf(addId), 1) 70 | } 71 | 72 | // // do not support cssnano minification here, use fis3 style plugins 73 | // // minification 74 | // if (process.env.NODE_ENV === 'production') { 75 | // plugins.push(require('cssnano')(assign({ 76 | // safe: true 77 | // }, options.cssnano))) 78 | // } 79 | currentId = id 80 | 81 | postcss(plugins) 82 | .process(css, opts) 83 | .then(function (res) { 84 | cache.set(key, res.css) 85 | cbk(null, res.css) 86 | }) 87 | } 88 | }) 89 | 90 | -------------------------------------------------------------------------------- /test2/fis-conf.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var parserVuePlugin = require('../index'); 3 | 4 | // 需要构建的文件 5 | fis.set('project.fileType.text', 'vue,map'); 6 | fis.set('project.files', ['src/**']); 7 | fis.set('project.ignore', fis.get('project.ignore').concat(['output/**', 'DS_store'])); 8 | 9 | // 模块化支持插件 10 | // https://github.com/fex-team/fis3-hook-commonjs (forwardDeclaration: true) 11 | fis.hook('commonjs', { 12 | extList: [ 13 | '.js', '.coffee', '.es6', '.jsx', '.vue', 14 | ], 15 | umd2commonjs: true, 16 | ignoreDependencies: [ 17 | 18 | ] 19 | }); 20 | 21 | // 禁用components,启用node_modules 22 | fis.unhook('components'); 23 | fis.hook('node_modules'); 24 | 25 | // 所有js文件 26 | fis.match('**.js', { 27 | isMod: true, 28 | rExt: 'js', 29 | useSameNameRequire: true 30 | }); 31 | 32 | // 编译vue组件 33 | fis.match('src/**.vue', { 34 | isMod: true, 35 | rExt: 'js', 36 | useSameNameRequire: true, 37 | parser: [ 38 | function(content, file, conf) { 39 | conf.runtimeOnly = true; 40 | return parserVuePlugin(content, file, conf); 41 | }, 42 | ] 43 | }); 44 | 45 | fis.match('src/**.vue:js', { 46 | isMod: true, 47 | rExt: 'js', 48 | useSameNameRequire: true, 49 | parser: [ 50 | fis.plugin('babel-6.x', { 51 | presets: ['es2015-loose', 'react', 'stage-3'] 52 | }), 53 | fis.plugin('translate-es3ify', null, 'append') 54 | ] 55 | }); 56 | 57 | fis.match('src/**.vue:jade', { 58 | parser: [ 59 | fis.plugin('jade', { 60 | // 61 | }) 62 | ] 63 | }) 64 | 65 | fis.match('src/{**.vue:less,**.less}', { 66 | rExt: 'css', 67 | parser: [fis.plugin('less-2.x')], 68 | postprocessor: fis.plugin('autoprefixer') 69 | }); 70 | 71 | fis.match('src/{**.vue:scss,**.scss}', { 72 | rExt: 'css', 73 | parser: [ 74 | fis.plugin('node-sass', { 75 | sourceMap: true, 76 | // sourceMapEmbed: true, 77 | }) 78 | ], 79 | postprocessor: fis.plugin('autoprefixer'), 80 | }); 81 | 82 | // 发布 83 | fis.match('/src/(**)', { 84 | release: '$1' 85 | }); 86 | 87 | // 88 | fis.match('src/(component/**.css)', { 89 | // packTo: 'component-all.css', 90 | release: 'static/$1' 91 | }); 92 | 93 | // 模块文件 94 | fis.match('/src/**.js', { 95 | parser: [ 96 | fis.plugin('babel-6.x', { 97 | presets: ['es2015-loose', 'react', 'stage-3'] 98 | }), 99 | fis.plugin('translate-es3ify', null, 'append') 100 | ] 101 | }); 102 | 103 | // 非模块文件 104 | fis.match('/src/js/engine/**.js', { 105 | parser: null, 106 | isMod: false 107 | }); 108 | 109 | // 页面直接引入的文件,不进行模块require包装 110 | fis.match('/src/js/page/**.js', { 111 | isMod: false 112 | }); 113 | 114 | // 打包 115 | fis.match('::package', { 116 | postpackager: fis.plugin('loader'), 117 | }); 118 | 119 | // 部署 120 | fis 121 | .media('local') 122 | .match('**', { 123 | deploy: fis.plugin('local-deliver', { 124 | to: path.join(__dirname, './output/') 125 | }) 126 | }); 127 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var objectAssign = require('object-assign'); 3 | var hashSum = require('hash-sum'); 4 | var compiler = require('vue-template-compiler'); 5 | 6 | var genId = require('./lib/gen-id'); 7 | var rewriteStyle = require('./lib/style-rewriter'); 8 | var compileTemplate = require('./lib/template-compiler'); 9 | var insertCSS = require('./lib/insert-css'); 10 | var replaceScopedFlag = require('./lib/replace-scoped-flag'); 11 | 12 | // exports 13 | module.exports = function(content, file, conf) { 14 | var scriptStr = ''; 15 | var output, configs, jsLang; 16 | 17 | // configs 18 | configs = objectAssign({ 19 | cssScopedFlag: '__vuec__', 20 | 21 | extractCSS: true, 22 | cssScopedIdPrefix: '_v-', 23 | cssScopedHashType: 'sum', 24 | cssScopedHashLength: 8, 25 | styleNameJoin: '', 26 | 27 | runtimeOnly: false, 28 | }, conf); 29 | 30 | // 兼容content为buffer的情况 31 | content = content.toString(); 32 | 33 | // generate css scope id 34 | var id = configs.cssScopedIdPrefix + genId(file, configs); 35 | 36 | // 兼容旧的cssScopedFlag 37 | if (configs.cssScopedFlag) { 38 | content = replaceScopedFlag(content, configs.cssScopedFlag, id); 39 | } 40 | 41 | // parse 42 | var output = compiler.parseComponent(content.toString(), { pad: true }); 43 | 44 | // check for scoped style nodes 45 | var hasScopedStyle = output.styles.some(function (style) { 46 | return style.scoped 47 | }); 48 | 49 | // script 50 | if (output.script) { 51 | scriptStr = output.script.content; 52 | jsLang = output.script.lang || 'js'; 53 | } else { 54 | scriptStr += 'module.exports = {}'; 55 | jsLang = 'js'; 56 | } 57 | 58 | // 部分内容以 js 的方式编译一次。如果要支持 cooffe 需要这么配置。 59 | // 只针对预编译语言 60 | // fis.match('*.vue:cooffe', { 61 | // parser: fis.plugin('cooffe') 62 | // }) 63 | scriptStr = fis.compile.partial(scriptStr, file, { 64 | ext: jsLang, 65 | isJsLike: true 66 | }); 67 | 68 | scriptStr += '\nvar __vue__options__;\n'; 69 | scriptStr += 'if(exports && exports.__esModule && exports.default){\n'; 70 | scriptStr += ' __vue__options__ = exports.default;\n'; 71 | scriptStr += '}else{\n'; 72 | scriptStr += ' __vue__options__ = module.exports;\n'; 73 | scriptStr += '}\n'; 74 | 75 | if(output.template){ 76 | var templateContent = fis.compile.partial(output.template.content, file, { 77 | ext: output.template.lang || 'html', 78 | isHtmlLike: true 79 | }); 80 | // runtimeOnly 81 | if(configs.runtimeOnly){ 82 | var result = compileTemplate(templateContent); 83 | if(result){ 84 | scriptStr += '__vue__options__.render =' + result.render + '\n'; 85 | scriptStr += '__vue__options__.staticRenderFns =' + result.staticRenderFns + '\n'; 86 | } 87 | }else{ 88 | // template 89 | scriptStr += '__vue__options__.template = ' + JSON.stringify(templateContent) + '\n'; 90 | } 91 | } 92 | 93 | if(hasScopedStyle){ 94 | // template 95 | scriptStr += '__vue__options__._scopeId = ' + JSON.stringify(id) + '\n'; 96 | } 97 | 98 | // style 99 | output.styles.forEach(function(item, index) { 100 | if(!item.content){ 101 | return; 102 | } 103 | 104 | // empty string, or all space line 105 | if(/^\s*$/.test(item.content)){ 106 | return; 107 | } 108 | 109 | // css也采用片段编译,更好的支持less、sass等其他语言 110 | var styleContent = fis.compile.partial(item.content, file, { 111 | ext: item.lang || 'css', 112 | isCssLike: true 113 | }); 114 | 115 | styleContent = rewriteStyle(id, styleContent, item.scoped, {}) 116 | 117 | if(!configs.extractCSS){ 118 | scriptStr += '\n;(' + insertCSS + ')(' + JSON.stringify(styleContent) + ');\n'; 119 | return; 120 | } 121 | 122 | var styleFileName, styleFile; 123 | 124 | if (output['styles'].length == 1) { 125 | styleFileName = file.realpathNoExt + configs.styleNameJoin + '.css'; 126 | } else { 127 | styleFileName = file.realpathNoExt + configs.styleNameJoin + '-' + index + '.css'; 128 | } 129 | 130 | styleFile = fis.file.wrap(styleFileName); 131 | 132 | styleFile.cache = file.cache; 133 | styleFile.isCssLike = true; 134 | styleFile.setContent(styleContent); 135 | fis.compile.process(styleFile); 136 | styleFile.links.forEach(function(derived) { 137 | file.addLink(derived); 138 | }); 139 | file.derived.push(styleFile); 140 | file.addRequire(styleFile.getId()); 141 | }); 142 | 143 | return scriptStr; 144 | }; 145 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # fis3-parser-vue-component 2 | 3 | > 由于本插件维护者开始使用webpack,本插件不再积极维护,建议使用fis的同学fork一份发布一个新插件。 4 | 5 | > 如果你已经在积极维护一个新的插件并且希望使用此插件的人转过去,请提一个issue,我在这里加上一个提示。 6 | 7 | ## 相关 8 | 9 | [vue + vuex + vue-router + webpack 快速开始脚手架](https://github.com/ccqgithub/vue-start). 10 | 11 | ## 注意 12 | 13 | - `5.5.0` for `vue@2.5.x`。 14 | 15 | - 版本: `>=4.10.0 <5.0.0`对应`vue@1.x`, 版本`>= 5.1.0`对应`vue@2.x`。 16 | 17 | - css依赖:css的依赖应该写在js中(如:`require('xxx.css')`), js中依赖的css优先于`style`标签。 18 | 19 | - FIS3 构建过程分为`单文件编译`和`打包过程`,`fis.match('component/**.vue:js')`这种配置属于片段编译,对应于单文件编译阶段,配置release等属性无效。打包过程的属性和插件应该针对`fis.match('component/**.vue')`和`fis.match('component/**.css')`配置。(具体见后面使用方法) 20 | 21 | ## 使用方法 22 | 23 | - 安装 24 | 25 | ``` 26 | npm install fis3-parser-vue-component --save-dev 27 | ``` 28 | 29 | - 基础配置 30 | 31 | ```js 32 | fis.match('src/**.vue', { 33 | isMod: true, 34 | rExt: 'js', 35 | useSameNameRequire: true, 36 | parser: [ 37 | fis.plugin('vue-component', { 38 | // vue@2.x runtimeOnly 39 |      runtimeOnly: true,         // vue@2.x 有runtimeOnly模式,为true时,template会在构建时转为render方法 40 | 41 | // styleNameJoin 42 | styleNameJoin: '', // 样式文件命名连接符 `component-xx-a.css` 43 | 44 | extractCSS: true, // 是否将css生成新的文件, 如果为false, 则会内联到js中 45 | 46 | // css scoped 47 | cssScopedIdPrefix: '_v-', // hash前缀:_v-23j232jj 48 | cssScopedHashType: 'sum', // hash生成模式,num:使用`hash-sum`, md5: 使用`fis.util.md5` 49 | cssScopedHashLength: 8, // hash 长度,cssScopedHashType为md5时有效 50 | 51 | cssScopedFlag: '__vuec__', // 兼容旧的ccs scoped模式而存在,此例子会将组件中所有的`__vuec__`替换为 `scoped id`,不需要设为空 52 | }) 53 | ], 54 | }); 55 | ``` 56 | 57 | - ES2015, coffee 等 58 | 59 | ```js 60 | // vue组件中ES2015处理 61 | fis.match('src/**.vue:js', { 62 | isMod: true, 63 | rExt: 'js', 64 | useSameNameRequire: true, 65 | parser: [ 66 | fis.plugin('babel-6.x', { 67 | presets: ['es2015-loose', 'react', 'stage-3'] 68 | }), 69 | fis.plugin('translate-es3ify', null, 'append') 70 | ] 71 | }); 72 | 73 | // vue组件中coffee片段处理。 74 | fis.match('src/**.vue:coffee', { 75 | parser: [ 76 | fis.plugin('cooffe') 77 | ] 78 | }) 79 | ``` 80 | 81 | - LESS, SASS 等 82 | 83 | ```js 84 | fis.match('src/**.vue:less', { 85 | rExt: 'css', 86 | parser: [fis.plugin('less-2.x')], 87 | postprocessor: fis.plugin('autoprefixer') 88 | }); 89 | 90 | fis.match('src/{**.vue:scss}', { 91 | rExt: 'css', 92 | parser: [ 93 | fis.plugin('node-sass', { 94 | sourceMap: true 95 | }) 96 | ], 97 | postprocessor: fis.plugin('autoprefixer'), 98 | }); 99 | ``` 100 | 101 | - Jade 等 102 | 103 | ```js 104 | fis.match('src/**.vue:jade', { 105 | parser: [ 106 | fis.plugin('jade', { 107 | // 108 | }) 109 | ] 110 | }) 111 | ``` 112 | 113 | - 产出,打包 114 | 115 | ```js 116 | fis.match('src/(**).vue', { 117 | release: 'static/vue/$1.js' 118 | }); 119 | 120 | fis.match('src/(component/**.css)', { 121 | packTo: 'component-all.css', 122 | release: 'static/$1' 123 | }); 124 | ``` 125 | 126 | ## 原理 127 | 128 | 参考[vue-loader](https://github.com/vuejs/vue-loader)源码,结合fis3的编译特性而编写,下面是parser阶段的主要过程: 129 | 130 | 1. 解析vue文件,找到其中的`style`,`template`,`script`标签。 131 | 132 | 2. 每一个`style`标签创建一个对应的虚拟文件,后缀为`lang`属性指定,默认`css`,你可以指定`less`或其它的后缀。对创建虚拟文件,一样会进行fis3的编译流程(属性`lang`的值决定该文件怎么编译),并加入当前文件的依赖。 133 | 134 | 3. `template`标签的内容为Vue组件的模板,`template`标签同样有`lang`属性,默认`html`,会进行html特性处理,模板的内容最终会输出到`module.exports.template`中。 135 | 136 | 4. `script`标签为文件最后输出的内容(加入模板字符串),支持`lang`属性。 137 | 138 | ## 组件编写规范 139 | 140 | `style`标签可以有多个,`template`和`script`标签只能有一个,具体请参考[vue 单文件组件](https://vuejs.org/v2/guide/single-file-components.html)。 141 | 142 | ## css scoped支持 143 | 144 | > 为了保证每一个组件样式的独立性,是当前组件定义的样式只在当前的组件内生效,引入css scoped机制。 145 | 146 | - 在style标签中使用scoped标志。 147 | 148 | ```css 149 | 150 | 151 | ``` 152 | 153 | - scoped标志会根据文件路径生成唯一的hash字符串(如:`_v-23j232jj` ) 154 | 155 | ## 测试demo 156 | 157 | > test 对应vue1, test2对应vue2 158 | 159 | `npm install` 160 | 161 | `cd test`, 编写代码… 162 | 163 | `npm install` 164 | 165 | `fis3 release` 166 | 167 | `fis3 server start` 168 | 169 | ## Vue2 JSX支持: 170 | 171 | > 使用vue 官方 babel插件[babel-plugin-transform-vue-jsx](https://github.com/vuejs/babel-plugin-transform-vue-jsx#usage). 172 | 173 | vue文件: 174 | ```html 175 | 198 | ``` 199 | 200 | 安装babel插件: 201 | ```shell 202 | npm install\ 203 | babel-plugin-syntax-jsx\ 204 | babel-plugin-transform-vue-jsx\ 205 | babel-helper-vue-jsx-merge-props\ 206 | --save-dev 207 | ``` 208 | 209 | fis相关配置 210 | ```js 211 | // vue组件中jsx片段处理。 212 | fis.match('src/**.vue:jsx', { 213 | parser: [ 214 | fis.plugin('babel-6.x', { 215 | presets: ['es2015-loose', 'stage-3'], 216 | plugins: ["transform-vue-jsx"] 217 | }), 218 | //fis.plugin('translate-es3ify', null, 'append') 219 | ] 220 | }) 221 | ``` 222 | -------------------------------------------------------------------------------- /test/src/js/engine/mod.js: -------------------------------------------------------------------------------- 1 | /** 2 | * file: mod.js 3 | * ver: 1.0.11 4 | * update: 2015/05/14 5 | * 6 | * https://github.com/fex-team/mod 7 | */ 8 | var require, define; 9 | 10 | (function(global) { 11 | if (require) return; // 避免重复加载而导致已定义模块丢失 12 | 13 | var head = document.getElementsByTagName('head')[0], 14 | loadingMap = {}, 15 | factoryMap = {}, 16 | modulesMap = {}, 17 | scriptsMap = {}, 18 | resMap = {}, 19 | pkgMap = {}; 20 | 21 | function createScript(url, onerror) { 22 | if (url in scriptsMap) return; 23 | scriptsMap[url] = true; 24 | 25 | var script = document.createElement('script'); 26 | if (onerror) { 27 | var tid = setTimeout(onerror, require.timeout); 28 | 29 | script.onerror = function() { 30 | clearTimeout(tid); 31 | onerror(); 32 | }; 33 | 34 | function onload() { 35 | clearTimeout(tid); 36 | } 37 | 38 | if ('onload' in script) { 39 | script.onload = onload; 40 | } else { 41 | script.onreadystatechange = function() { 42 | if (this.readyState == 'loaded' || this.readyState == 'complete') { 43 | onload(); 44 | } 45 | } 46 | } 47 | } 48 | script.type = 'text/javascript'; 49 | script.src = url; 50 | head.appendChild(script); 51 | return script; 52 | } 53 | 54 | function loadScript(id, callback, onerror) { 55 | var queue = loadingMap[id] || (loadingMap[id] = []); 56 | queue.push(callback); 57 | 58 | // 59 | // resource map query 60 | // 61 | var res = resMap[id] || resMap[id + '.js'] || {}; 62 | var pkg = res.pkg; 63 | var url; 64 | 65 | if (pkg) { 66 | url = pkgMap[pkg].url; 67 | } else { 68 | url = res.url || id; 69 | } 70 | 71 | createScript(url, onerror && function() { 72 | onerror(id); 73 | }); 74 | } 75 | 76 | define = function(id, factory) { 77 | id = id.replace(/\.js$/i, ''); 78 | factoryMap[id] = factory; 79 | 80 | var queue = loadingMap[id]; 81 | if (queue) { 82 | for (var i = 0, n = queue.length; i < n; i++) { 83 | queue[i](); 84 | } 85 | delete loadingMap[id]; 86 | } 87 | }; 88 | 89 | require = function(id) { 90 | 91 | // compatible with require([dep, dep2...]) syntax. 92 | if (id && id.splice) { 93 | return require.async.apply(this, arguments); 94 | } 95 | 96 | id = require.alias(id); 97 | 98 | var mod = modulesMap[id]; 99 | if (mod) { 100 | return mod.exports; 101 | } 102 | 103 | // 104 | // init module 105 | // 106 | var factory = factoryMap[id]; 107 | if (!factory) { 108 | throw '[ModJS] Cannot find module `' + id + '`'; 109 | } 110 | 111 | mod = modulesMap[id] = { 112 | exports: {} 113 | }; 114 | 115 | // 116 | // factory: function OR value 117 | // 118 | var ret = (typeof factory == 'function') ? factory.apply(mod, [require, mod.exports, mod]) : factory; 119 | 120 | if (ret) { 121 | mod.exports = ret; 122 | } 123 | return mod.exports; 124 | }; 125 | 126 | require.async = function(names, onload, onerror) { 127 | if (typeof names == 'string') { 128 | names = [names]; 129 | } 130 | 131 | var needMap = {}; 132 | var needNum = 0; 133 | 134 | function findNeed(depArr) { 135 | for (var i = 0, n = depArr.length; i < n; i++) { 136 | // 137 | // skip loading or loaded 138 | // 139 | var dep = require.alias(depArr[i]); 140 | 141 | if (dep in factoryMap) { 142 | // check whether loaded resource's deps is loaded or not 143 | var child = resMap[dep] || resMap[dep + '.js']; 144 | if (child && 'deps' in child) { 145 | findNeed(child.deps); 146 | } 147 | continue; 148 | } 149 | 150 | if (dep in needMap) { 151 | continue; 152 | } 153 | 154 | needMap[dep] = true; 155 | needNum++; 156 | loadScript(dep, updateNeed, onerror); 157 | 158 | var child = resMap[dep] || resMap[dep + '.js']; 159 | if (child && 'deps' in child) { 160 | findNeed(child.deps); 161 | } 162 | } 163 | } 164 | 165 | function updateNeed() { 166 | if (0 == needNum--) { 167 | var args = []; 168 | for (var i = 0, n = names.length; i < n; i++) { 169 | args[i] = require(names[i]); 170 | } 171 | 172 | onload && onload.apply(global, args); 173 | } 174 | } 175 | 176 | findNeed(names); 177 | updateNeed(); 178 | }; 179 | 180 | require.resourceMap = function(obj) { 181 | var k, col; 182 | 183 | // merge `res` & `pkg` fields 184 | col = obj.res; 185 | for (k in col) { 186 | if (col.hasOwnProperty(k)) { 187 | resMap[k] = col[k]; 188 | } 189 | } 190 | 191 | col = obj.pkg; 192 | for (k in col) { 193 | if (col.hasOwnProperty(k)) { 194 | pkgMap[k] = col[k]; 195 | } 196 | } 197 | }; 198 | 199 | require.loadJs = function(url) { 200 | createScript(url); 201 | }; 202 | 203 | require.loadCss = function(cfg) { 204 | if (cfg.content) { 205 | var sty = document.createElement('style'); 206 | sty.type = 'text/css'; 207 | 208 | if (sty.styleSheet) { // IE 209 | sty.styleSheet.cssText = cfg.content; 210 | } else { 211 | sty.innerHTML = cfg.content; 212 | } 213 | head.appendChild(sty); 214 | } else if (cfg.url) { 215 | var link = document.createElement('link'); 216 | link.href = cfg.url; 217 | link.rel = 'stylesheet'; 218 | link.type = 'text/css'; 219 | head.appendChild(link); 220 | } 221 | }; 222 | 223 | 224 | require.alias = function(id) { 225 | return id.replace(/\.js$/i, ''); 226 | }; 227 | 228 | require.timeout = 5000; 229 | 230 | })(this); 231 | -------------------------------------------------------------------------------- /test2/src/js/engine/mod.js: -------------------------------------------------------------------------------- 1 | /** 2 | * file: mod.js 3 | * ver: 1.0.11 4 | * update: 2015/05/14 5 | * 6 | * https://github.com/fex-team/mod 7 | */ 8 | var require, define; 9 | 10 | (function(global) { 11 | if (require) return; // 避免重复加载而导致已定义模块丢失 12 | 13 | var head = document.getElementsByTagName('head')[0], 14 | loadingMap = {}, 15 | factoryMap = {}, 16 | modulesMap = {}, 17 | scriptsMap = {}, 18 | resMap = {}, 19 | pkgMap = {}; 20 | 21 | function createScript(url, onerror) { 22 | if (url in scriptsMap) return; 23 | scriptsMap[url] = true; 24 | 25 | var script = document.createElement('script'); 26 | if (onerror) { 27 | var tid = setTimeout(onerror, require.timeout); 28 | 29 | script.onerror = function() { 30 | clearTimeout(tid); 31 | onerror(); 32 | }; 33 | 34 | function onload() { 35 | clearTimeout(tid); 36 | } 37 | 38 | if ('onload' in script) { 39 | script.onload = onload; 40 | } else { 41 | script.onreadystatechange = function() { 42 | if (this.readyState == 'loaded' || this.readyState == 'complete') { 43 | onload(); 44 | } 45 | } 46 | } 47 | } 48 | script.type = 'text/javascript'; 49 | script.src = url; 50 | head.appendChild(script); 51 | return script; 52 | } 53 | 54 | function loadScript(id, callback, onerror) { 55 | var queue = loadingMap[id] || (loadingMap[id] = []); 56 | queue.push(callback); 57 | 58 | // 59 | // resource map query 60 | // 61 | var res = resMap[id] || resMap[id + '.js'] || {}; 62 | var pkg = res.pkg; 63 | var url; 64 | 65 | if (pkg) { 66 | url = pkgMap[pkg].url; 67 | } else { 68 | url = res.url || id; 69 | } 70 | 71 | createScript(url, onerror && function() { 72 | onerror(id); 73 | }); 74 | } 75 | 76 | define = function(id, factory) { 77 | id = id.replace(/\.js$/i, ''); 78 | factoryMap[id] = factory; 79 | 80 | var queue = loadingMap[id]; 81 | if (queue) { 82 | for (var i = 0, n = queue.length; i < n; i++) { 83 | queue[i](); 84 | } 85 | delete loadingMap[id]; 86 | } 87 | }; 88 | 89 | require = function(id) { 90 | 91 | // compatible with require([dep, dep2...]) syntax. 92 | if (id && id.splice) { 93 | return require.async.apply(this, arguments); 94 | } 95 | 96 | id = require.alias(id); 97 | 98 | var mod = modulesMap[id]; 99 | if (mod) { 100 | return mod.exports; 101 | } 102 | 103 | // 104 | // init module 105 | // 106 | var factory = factoryMap[id]; 107 | if (!factory) { 108 | throw '[ModJS] Cannot find module `' + id + '`'; 109 | } 110 | 111 | mod = modulesMap[id] = { 112 | exports: {} 113 | }; 114 | 115 | // 116 | // factory: function OR value 117 | // 118 | var ret = (typeof factory == 'function') ? factory.apply(mod, [require, mod.exports, mod]) : factory; 119 | 120 | if (ret) { 121 | mod.exports = ret; 122 | } 123 | return mod.exports; 124 | }; 125 | 126 | require.async = function(names, onload, onerror) { 127 | if (typeof names == 'string') { 128 | names = [names]; 129 | } 130 | 131 | var needMap = {}; 132 | var needNum = 0; 133 | 134 | function findNeed(depArr) { 135 | for (var i = 0, n = depArr.length; i < n; i++) { 136 | // 137 | // skip loading or loaded 138 | // 139 | var dep = require.alias(depArr[i]); 140 | 141 | if (dep in factoryMap) { 142 | // check whether loaded resource's deps is loaded or not 143 | var child = resMap[dep] || resMap[dep + '.js']; 144 | if (child && 'deps' in child) { 145 | findNeed(child.deps); 146 | } 147 | continue; 148 | } 149 | 150 | if (dep in needMap) { 151 | continue; 152 | } 153 | 154 | needMap[dep] = true; 155 | needNum++; 156 | loadScript(dep, updateNeed, onerror); 157 | 158 | var child = resMap[dep] || resMap[dep + '.js']; 159 | if (child && 'deps' in child) { 160 | findNeed(child.deps); 161 | } 162 | } 163 | } 164 | 165 | function updateNeed() { 166 | if (0 == needNum--) { 167 | var args = []; 168 | for (var i = 0, n = names.length; i < n; i++) { 169 | args[i] = require(names[i]); 170 | } 171 | 172 | onload && onload.apply(global, args); 173 | } 174 | } 175 | 176 | findNeed(names); 177 | updateNeed(); 178 | }; 179 | 180 | require.resourceMap = function(obj) { 181 | var k, col; 182 | 183 | // merge `res` & `pkg` fields 184 | col = obj.res; 185 | for (k in col) { 186 | if (col.hasOwnProperty(k)) { 187 | resMap[k] = col[k]; 188 | } 189 | } 190 | 191 | col = obj.pkg; 192 | for (k in col) { 193 | if (col.hasOwnProperty(k)) { 194 | pkgMap[k] = col[k]; 195 | } 196 | } 197 | }; 198 | 199 | require.loadJs = function(url) { 200 | createScript(url); 201 | }; 202 | 203 | require.loadCss = function(cfg) { 204 | if (cfg.content) { 205 | var sty = document.createElement('style'); 206 | sty.type = 'text/css'; 207 | 208 | if (sty.styleSheet) { // IE 209 | sty.styleSheet.cssText = cfg.content; 210 | } else { 211 | sty.innerHTML = cfg.content; 212 | } 213 | head.appendChild(sty); 214 | } else if (cfg.url) { 215 | var link = document.createElement('link'); 216 | link.href = cfg.url; 217 | link.rel = 'stylesheet'; 218 | link.type = 'text/css'; 219 | head.appendChild(link); 220 | } 221 | }; 222 | 223 | 224 | require.alias = function(id) { 225 | return id.replace(/\.js$/i, ''); 226 | }; 227 | 228 | require.timeout = 5000; 229 | 230 | })(this); 231 | --------------------------------------------------------------------------------