├── test ├── fixtures │ ├── style-import.css │ ├── duplicate-cssm.css │ ├── template-import.pug │ ├── style-import-scoped.css │ ├── markdown.vue │ ├── script-import.vue │ ├── template-import.html │ ├── template-import.vue │ ├── custom-directive.vue │ ├── template-pre.vue │ ├── logo.png │ ├── template-import-pre.vue │ ├── es2015.vue │ ├── multiple-roots-template.vue │ ├── empty-style.vue │ ├── postcss.vue │ ├── unit-test.js │ ├── media-query.vue │ ├── style-import.vue │ ├── supports-query.vue │ ├── script-import.js │ ├── custom-module.vue │ ├── ssr-style.js │ ├── css-modules-simple.vue │ ├── multiple-rules.js │ ├── ssr-scoped-style.js │ ├── extract-css.vue │ ├── named-exports.vue │ ├── style-import-twice-sub.vue │ ├── index.html │ ├── custom-options.vue │ ├── duplicate-cssm.js │ ├── multiple-rules-1.vue │ ├── multiple-rules-2.vue │ ├── custom-module.js │ ├── ts.vue │ ├── duplicate-cssm.vue │ ├── template-pre.js │ ├── entry.js │ ├── functional-style.vue │ ├── custom-blocks.vue │ ├── App.ts │ ├── extend.vue │ ├── css-modules-extend.vue │ ├── template-comment.vue │ ├── style-import-twice.vue │ ├── basic.vue │ ├── css-modules.vue │ ├── resolve.vue │ ├── custom-import.vue │ ├── pre.vue │ ├── functional-root.vue │ ├── extract-css-chunks.vue │ ├── ssr-style.vue │ ├── functional.vue │ ├── custom-language.vue │ ├── transform.vue │ ├── scoped-css.vue │ └── prettier-bug.vue ├── .eslintrc.js ├── mock-loaders │ ├── css.js │ ├── html.js │ ├── identity.js │ ├── js.js │ ├── yaml.js │ ├── docs.js │ ├── blog.js │ ├── i18n.js │ └── query.js ├── script.spec.js ├── custom.spec.js ├── core.spec.js ├── utils.js └── ssr.spec.js ├── example ├── test.pug ├── index.html ├── main.js ├── debugger.js ├── source.vue └── webpack.config.js ├── .babelrc ├── .npmignore ├── .eslintrc.js ├── .gitignore ├── docs ├── .vuepress │ ├── public │ │ ├── hot-reload.gif │ │ └── _redirects │ └── config.js ├── zh │ ├── guide │ │ ├── testing.md │ │ ├── functional.md │ │ ├── hot-reload.md │ │ ├── extract-css.md │ │ ├── linting.md │ │ ├── asset-url.md │ │ ├── scoped-css.md │ │ ├── custom-blocks.md │ │ ├── README.md │ │ └── css-modules.md │ ├── README.md │ ├── options.md │ └── spec.md ├── guide │ ├── testing.md │ ├── functional.md │ ├── extract-css.md │ ├── linting.md │ ├── hot-reload.md │ ├── custom-blocks.md │ ├── scoped-css.md │ ├── asset-url.md │ ├── README.md │ └── css-modules.md ├── ru │ ├── guide │ │ ├── testing.md │ │ ├── functional.md │ │ ├── extract-css.md │ │ ├── linting.md │ │ ├── custom-blocks.md │ │ ├── hot-reload.md │ │ ├── asset-url.md │ │ ├── scoped-css.md │ │ ├── README.md │ │ └── css-modules.md │ └── README.md ├── README.md └── options.md ├── third-libs ├── querystring │ ├── index.js │ ├── Readme.md │ ├── License.md │ ├── encode.js │ ├── decode.js │ └── package.json ├── vue-template-compiler │ ├── types │ │ ├── tsconfig.json │ │ └── test.ts │ ├── index.js │ └── package.json ├── component-compiler-utils-master │ ├── lib │ │ ├── stylePlugins │ │ │ ├── trim.ts │ │ │ └── scoped.ts │ │ ├── index.ts │ │ ├── types.ts │ │ ├── templateCompilerModules │ │ │ ├── assetUrl.ts │ │ │ ├── utils.ts │ │ │ └── srcset.ts │ │ ├── styleProcessors │ │ │ └── index.ts │ │ ├── parse.ts │ │ └── compileStyle.ts │ ├── tsconfig.json │ └── package.json ├── loader-utils │ ├── getCurrentRequest.js │ ├── getRemainingRequest.js │ ├── parseString.js │ ├── getOptions.js │ ├── isUrlRequest.js │ ├── index.js │ ├── parseQuery.js │ ├── stringifyRequest.js │ ├── urlToRequest.js │ ├── getHashDigest.js │ └── interpolateName.js └── compileStyle.ts ├── .github └── ISSUE_TEMPLATE.md ├── tsconfig.json ├── appveyor.yml ├── .vscode └── launch.json ├── .circleci └── config.yml ├── lib ├── index.d.ts ├── codegen │ ├── utils.js │ ├── customBlocks.js │ └── hotReload.js ├── select.js ├── loaders │ ├── stylePostLoader.js │ └── templateLoader.js └── runtime │ └── componentNormalizer.js ├── LICENSE └── package.json /test/fixtures/style-import.css: -------------------------------------------------------------------------------- 1 | h1 { color: red; } 2 | -------------------------------------------------------------------------------- /test/fixtures/duplicate-cssm.css: -------------------------------------------------------------------------------- 1 | @value color: red; 2 | -------------------------------------------------------------------------------- /test/fixtures/template-import.pug: -------------------------------------------------------------------------------- 1 | div 2 | h1 hello 3 | -------------------------------------------------------------------------------- /test/fixtures/style-import-scoped.css: -------------------------------------------------------------------------------- 1 | h1 { color: green; } 2 | -------------------------------------------------------------------------------- /example/test.pug: -------------------------------------------------------------------------------- 1 | div(ok) 2 | h1(:class="$style.red") hello 3 | -------------------------------------------------------------------------------- /test/fixtures/markdown.vue: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /test/fixtures/script-import.vue: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/template-import.html: -------------------------------------------------------------------------------- 1 |
2 |

hello

3 |
4 | -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | ["env", { "modules": false }] 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /example/index.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | -------------------------------------------------------------------------------- /test/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /test/fixtures/template-import.vue: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | example 2 | test 3 | *.yml 4 | *.log 5 | yarn.lock 6 | tsconfig.json 7 | docs 8 | -------------------------------------------------------------------------------- /test/fixtures/custom-directive.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/template-pre.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /test/fixtures/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xixizhangfe/vue-loader/HEAD/test/fixtures/logo.png -------------------------------------------------------------------------------- /test/fixtures/template-import-pre.vue: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: ['plugin:vue-libs/recommended'] 4 | } 5 | -------------------------------------------------------------------------------- /test/fixtures/es2015.vue: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /test/fixtures/multiple-roots-template.vue: -------------------------------------------------------------------------------- 1 | 5 | -------------------------------------------------------------------------------- /test/fixtures/empty-style.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 7 | -------------------------------------------------------------------------------- /test/fixtures/postcss.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/unit-test.js: -------------------------------------------------------------------------------- 1 | describe('example', () => { 2 | it('basic', done => { 3 | done() 4 | }) 5 | }) 6 | -------------------------------------------------------------------------------- /test/mock-loaders/css.js: -------------------------------------------------------------------------------- 1 | module.exports = function (content) { 2 | return content.replace(/#f00/, '#00f') 3 | } 4 | -------------------------------------------------------------------------------- /test/mock-loaders/html.js: -------------------------------------------------------------------------------- 1 | module.exports = function (content) { 2 | return content.replace(/red/, 'green') 3 | } 4 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | exploration 3 | node_modules 4 | *.log 5 | example/dist 6 | docs/.vuepress/dist 7 | test/.cache -------------------------------------------------------------------------------- /test/mock-loaders/identity.js: -------------------------------------------------------------------------------- 1 | module.exports = function (source, map) { 2 | this.callback(null, source, map) 3 | } 4 | -------------------------------------------------------------------------------- /test/fixtures/media-query.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /docs/.vuepress/public/hot-reload.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xixizhangfe/vue-loader/HEAD/docs/.vuepress/public/hot-reload.gif -------------------------------------------------------------------------------- /test/fixtures/style-import.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /test/mock-loaders/js.js: -------------------------------------------------------------------------------- 1 | module.exports = function (content) { 2 | return content.replace(/Hello from Component A!/, 'Changed!') 3 | } 4 | -------------------------------------------------------------------------------- /example/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Foo from './source.vue' 3 | 4 | new Vue({ 5 | el: '#app', 6 | render: h => h(Foo) 7 | }) 8 | -------------------------------------------------------------------------------- /test/fixtures/supports-query.vue: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /test/fixtures/script-import.js: -------------------------------------------------------------------------------- 1 | export default { 2 | data () { 3 | return { 4 | msg: 'Hello from Component A!' 5 | } 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/custom-module.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixtures/ssr-style.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './ssr-style.vue' 3 | 4 | export default () => new Vue({ 5 | render: h => h(App) 6 | }) 7 | -------------------------------------------------------------------------------- /test/fixtures/css-modules-simple.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 10 | -------------------------------------------------------------------------------- /test/fixtures/multiple-rules.js: -------------------------------------------------------------------------------- 1 | import Rule1 from './multiple-rules-1.vue' 2 | import Rule2 from './multiple-rules-2.vue' 3 | 4 | window.rules = [Rule1, Rule2] 5 | -------------------------------------------------------------------------------- /test/fixtures/ssr-scoped-style.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import App from './scoped-css.vue' 3 | 4 | export default () => new Vue({ 5 | render: h => h(App) 6 | }) 7 | -------------------------------------------------------------------------------- /example/debugger.js: -------------------------------------------------------------------------------- 1 | module.exports = function (...args) { 2 | this.callback(null, ...args) 3 | } 4 | 5 | module.exports.pitch = function (request) { 6 | // debug 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/extract-css.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 11 | -------------------------------------------------------------------------------- /test/fixtures/named-exports.vue: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /third-libs/querystring/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | exports.decode = exports.parse = require('./decode'); 4 | exports.encode = exports.stringify = require('./encode'); 5 | -------------------------------------------------------------------------------- /test/fixtures/style-import-twice-sub.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /test/fixtures/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /test/fixtures/custom-options.vue: -------------------------------------------------------------------------------- 1 | 2 | describe('example', function () { 3 | it('basic', function (done) { 4 | done(); 5 | }) 6 | }) 7 | 8 | -------------------------------------------------------------------------------- /test/fixtures/duplicate-cssm.js: -------------------------------------------------------------------------------- 1 | import values from './duplicate-cssm.css' 2 | import Comp from './duplicate-cssm.vue' 3 | 4 | export { values } 5 | export default Comp 6 | 7 | window.exports = values 8 | -------------------------------------------------------------------------------- /test/fixtures/multiple-rules-1.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /test/fixtures/multiple-rules-2.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /test/fixtures/custom-module.js: -------------------------------------------------------------------------------- 1 | module.exports = [ 2 | { 3 | postTransformNode: el => { 4 | if (el.staticClass) { 5 | el.staticClass = '"red blue"' 6 | } 7 | } 8 | } 9 | ] 10 | -------------------------------------------------------------------------------- /test/mock-loaders/yaml.js: -------------------------------------------------------------------------------- 1 | var yaml = require('js-yaml') 2 | 3 | module.exports = function (source) { 4 | this.cacheable && this.cacheable() 5 | var res = yaml.safeLoad(source) 6 | return JSON.stringify(res) 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/ts.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /test/mock-loaders/docs.js: -------------------------------------------------------------------------------- 1 | module.exports = function (source, map) { 2 | this.callback(null, 3 | `export default Component => { 4 | Component.options.__docs = ${JSON.stringify(source)} 5 | }`, 6 | map) 7 | } 8 | -------------------------------------------------------------------------------- /test/fixtures/duplicate-cssm.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 12 | -------------------------------------------------------------------------------- /test/fixtures/template-pre.js: -------------------------------------------------------------------------------- 1 | import Comp1 from './template-pre.vue' 2 | import Comp2 from './template-import-pre.vue' 3 | import html from './template-import.pug' 4 | 5 | window.exports = { 6 | Comp1, 7 | Comp2, 8 | html 9 | } 10 | -------------------------------------------------------------------------------- /test/fixtures/entry.js: -------------------------------------------------------------------------------- 1 | import Component from '~target' 2 | import * as exports from '~target' 3 | 4 | if (typeof window !== 'undefined') { 5 | window.module = Component 6 | window.exports = exports 7 | } 8 | 9 | export default Component 10 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "esnext", 4 | "moduleResolution": "node", 5 | "strict": true, 6 | "target": "es6", 7 | "baseUrl": "." 8 | }, 9 | "exclude": [ 10 | "node_modules" 11 | ] 12 | } 13 | -------------------------------------------------------------------------------- /test/fixtures/functional-style.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 13 | -------------------------------------------------------------------------------- /test/fixtures/custom-blocks.vue: -------------------------------------------------------------------------------- 1 | 2 | en: 3 | hello: "hello world" 4 | ja: 5 | hello: "こんにちは、世界" 6 | 7 | 8 | ## foo 9 | 10 | 16 | -------------------------------------------------------------------------------- /test/fixtures/App.ts: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | export default Vue.extend({ 4 | data () { 5 | return { 6 | msg: 'Hello from Component A!' 7 | } 8 | }, 9 | methods: { 10 | someMethod (arg: string): string { 11 | return 'hello' 12 | } 13 | } 14 | }) 15 | -------------------------------------------------------------------------------- /test/fixtures/extend.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 16 | -------------------------------------------------------------------------------- /test/mock-loaders/blog.js: -------------------------------------------------------------------------------- 1 | function normalize (code) { 2 | return code.split(/\r?\n/).map(function (line) { return line }).join('') 3 | } 4 | 5 | module.exports = function (source) { 6 | var code = "module.exports = function (Component) { Component.options.__blog = '" + source + "' }" 7 | return normalize(code) 8 | } 9 | -------------------------------------------------------------------------------- /third-libs/vue-template-compiler/types/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "target": "es5", 4 | "module": "commonjs", 5 | "moduleResolution": "node", 6 | "strict": true, 7 | "noEmit": true 8 | }, 9 | "compileOnSave": false, 10 | "include": [ 11 | "**/*.ts" 12 | ] 13 | } 14 | -------------------------------------------------------------------------------- /appveyor.yml: -------------------------------------------------------------------------------- 1 | environment: 2 | nodejs_version: "8" 3 | 4 | install: 5 | - ps: Install-Product node $env:nodejs_version 6 | - yarn 7 | 8 | test_script: 9 | - git --version 10 | - node --version 11 | - yarn --version 12 | - yarn test 13 | 14 | cache: 15 | - node_modules -> yarn.lock 16 | 17 | build: off 18 | -------------------------------------------------------------------------------- /test/fixtures/css-modules-extend.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 14 | 15 | -------------------------------------------------------------------------------- /test/fixtures/template-comment.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 17 | -------------------------------------------------------------------------------- /test/fixtures/style-import-twice.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | -------------------------------------------------------------------------------- /test/fixtures/basic.vue: -------------------------------------------------------------------------------- 1 | 4 | 5 | 14 | 15 | 18 | 19 | 20 | 25 | -------------------------------------------------------------------------------- /test/fixtures/css-modules.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 17 | 18 | 21 | -------------------------------------------------------------------------------- /test/fixtures/resolve.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /test/fixtures/custom-import.vue: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 17 | 18 | 23 | -------------------------------------------------------------------------------- /test/mock-loaders/i18n.js: -------------------------------------------------------------------------------- 1 | module.exports = function (source) { 2 | var value = typeof source === 'string' ? JSON.parse(source) : source 3 | var jsonString = JSON.stringify(value).replace(/\u2028/g, '\\u2028').replace(/\u2029/g, '\\u2029') 4 | var code = 'module.exports = function (Component) { Component.options.__i18n = ' + JSON.stringify(jsonString) + ' }' 5 | this.callback(null, code) 6 | } 7 | -------------------------------------------------------------------------------- /third-libs/component-compiler-utils-master/lib/stylePlugins/trim.ts: -------------------------------------------------------------------------------- 1 | import { Root } from 'postcss' 2 | import * as postcss from 'postcss' 3 | 4 | export default postcss.plugin('trim', () => (css: Root) => { 5 | css.walk(({ type, raws }) => { 6 | if (type === 'rule' || type === 'atrule') { 7 | if (raws.before) raws.before = '\n' 8 | if (raws.after) raws.after = '\n' 9 | } 10 | }) 11 | }) 12 | -------------------------------------------------------------------------------- /example/source.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 15 | 16 | 21 | 22 | 23 | export default comp => { 24 | console.log(comp.options.data()) 25 | } 26 | 27 | -------------------------------------------------------------------------------- /test/fixtures/pre.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 15 | 16 | 23 | -------------------------------------------------------------------------------- /third-libs/querystring/Readme.md: -------------------------------------------------------------------------------- 1 | # querystring 2 | 3 | [![Build Status](https://secure.travis-ci.org/Gozala/querystring.png)](http://travis-ci.org/Gozala/querystring) 4 | 5 | 6 | [![Browser support](http://ci.testling.com/Gozala/querystring.png)](http://ci.testling.com/Gozala/querystring) 7 | 8 | 9 | 10 | Node's querystring module for all engines. 11 | 12 | ## Install ## 13 | 14 | npm install querystring 15 | 16 | -------------------------------------------------------------------------------- /test/fixtures/functional-root.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 19 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | "version": "0.2.0", 3 | "configurations": [ 4 | { 5 | "type": "chrome", 6 | "request": "launch", 7 | "name": "vuejs: chrome", 8 | "url": "http://localhost:8080", 9 | "webRoot": "${workspaceFolder}", 10 | "breakOnLoad": true, 11 | "sourceMaps": true 12 | // "sourceMapPathOverrides": { 13 | // "webpack:///./src/*": "${webRoot}/*" 14 | // } 15 | } 16 | ] 17 | } 18 | -------------------------------------------------------------------------------- /test/fixtures/extract-css-chunks.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | 17 | 22 | -------------------------------------------------------------------------------- /third-libs/loader-utils/getCurrentRequest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function getCurrentRequest(loaderContext) { 4 | if (loaderContext.currentRequest) { 5 | return loaderContext.currentRequest; 6 | } 7 | 8 | const request = loaderContext.loaders 9 | .slice(loaderContext.loaderIndex) 10 | .map((obj) => obj.request) 11 | .concat([loaderContext.resource]); 12 | 13 | return request.join('!'); 14 | } 15 | 16 | module.exports = getCurrentRequest; 17 | -------------------------------------------------------------------------------- /third-libs/loader-utils/getRemainingRequest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function getRemainingRequest(loaderContext) { 4 | if (loaderContext.remainingRequest) { 5 | return loaderContext.remainingRequest; 6 | } 7 | 8 | const request = loaderContext.loaders 9 | .slice(loaderContext.loaderIndex + 1) 10 | .map((obj) => obj.request) 11 | .concat([loaderContext.resource]); 12 | 13 | return request.join('!'); 14 | } 15 | 16 | module.exports = getRemainingRequest; 17 | -------------------------------------------------------------------------------- /test/fixtures/ssr-style.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 20 | 21 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /test/mock-loaders/query.js: -------------------------------------------------------------------------------- 1 | module.exports = function (content) { 2 | const query = this.resourceQuery.slice(1) 3 | 4 | if (/change/.test(query)) { 5 | return ` 6 | 9 | 18 | ` 19 | } 20 | 21 | return content 22 | } 23 | -------------------------------------------------------------------------------- /docs/zh/guide/testing.md: -------------------------------------------------------------------------------- 1 | # 测试 2 | 3 | - [Vue CLI](https://github.com/vuejs/vue-cli) 提供了预配置的单元测试和 e2e 测试安装。 4 | 5 | - 如果你有兴趣为 `*.vue` 文件手动设置单元测试,请查询 [@vue/test-utils](https://vue-test-utils.vuejs.org/zh/) 的文档,这份文档涵盖了对 [mocha-webpack](https://vue-test-utils.vuejs.org/zh/guides/#%E7%94%A8-mocha-%E5%92%8C-webpack-%E6%B5%8B%E8%AF%95%E5%8D%95%E6%96%87%E4%BB%B6%E7%BB%84%E4%BB%B6) 或 [Jest](https://vue-test-utils.vuejs.org/zh/guides/#%E7%94%A8-jest-%E6%B5%8B%E8%AF%95%E5%8D%95%E6%96%87%E4%BB%B6%E7%BB%84%E4%BB%B6) 的设置。 6 | -------------------------------------------------------------------------------- /docs/guide/testing.md: -------------------------------------------------------------------------------- 1 | # Testing 2 | 3 | - [Vue CLI](https://github.com/vuejs/vue-cli) offers pre-configured unit testing and e2e testing setups. 4 | 5 | - If you are interested in manually setting up unit tests for `*.vue` files, consult the docs for [@vue/test-utils](https://vue-test-utils.vuejs.org), which covers setup with [mocha-webpack](https://vue-test-utils.vuejs.org/guides/#testing-single-file-components-with-mocha-webpack) or [Jest](https://vue-test-utils.vuejs.org/guides/#testing-single-file-components-with-jest). 6 | -------------------------------------------------------------------------------- /test/fixtures/functional.vue: -------------------------------------------------------------------------------- 1 | 12 | 13 | 23 | -------------------------------------------------------------------------------- /third-libs/loader-utils/parseString.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | function parseString(str) { 4 | try { 5 | if (str[0] === '"') { 6 | return JSON.parse(str); 7 | } 8 | 9 | if (str[0] === "'" && str.substr(str.length - 1) === "'") { 10 | return parseString( 11 | str 12 | .replace(/\\.|"/g, (x) => (x === '"' ? '\\"' : x)) 13 | .replace(/^'|'$/g, '"') 14 | ); 15 | } 16 | 17 | return JSON.parse('"' + str + '"'); 18 | } catch (e) { 19 | return str; 20 | } 21 | } 22 | 23 | module.exports = parseString; 24 | -------------------------------------------------------------------------------- /test/fixtures/custom-language.vue: -------------------------------------------------------------------------------- 1 | 2 | describe('example', () => { 3 | it('basic', done => { 4 | done(); 5 | }) 6 | }) 7 | 8 | 9 | 10 | This is example documentation for a component. 11 | 12 | 13 | 16 | 17 | 26 | 27 | 32 | -------------------------------------------------------------------------------- /docs/zh/guide/functional.md: -------------------------------------------------------------------------------- 1 | # 函数式组件 2 | 3 | 在一个 `*.vue` 文件中以单文件形式定义的函数式组件,现在对于模板编译、scoped CSS 和热重载也有了良好的支持。 4 | 5 | 要声明一个应该编译为函数式组件的模板,请将 `functional` 特性添加到模板块中。这样做以后就可以省略 ` 25 | 26 | 31 | ``` 32 | 33 | Vue Loader 还提供了很多酷炫的特性: 34 | 35 | - 允许为 Vue 组件的每个部分使用其它的 webpack loader,例如在 ` 49 | 50 | 56 | 57 | 58 | 59 | 66 | -------------------------------------------------------------------------------- /lib/select.js: -------------------------------------------------------------------------------- 1 | module.exports = function selectBlock ( 2 | descriptor, 3 | loaderContext, 4 | query, 5 | appendExtension 6 | ) { 7 | // template 8 | if (query.type === `template`) { 9 | if (appendExtension) { 10 | loaderContext.resourcePath += '.' + (descriptor.template.lang || 'html') 11 | } 12 | loaderContext.callback( 13 | null, 14 | descriptor.template.content, 15 | descriptor.template.map 16 | ) 17 | return 18 | } 19 | 20 | // script 21 | if (query.type === `script`) { 22 | if (appendExtension) { 23 | loaderContext.resourcePath += '.' + (descriptor.script.lang || 'js') 24 | } 25 | loaderContext.callback( 26 | null, 27 | descriptor.script.content, 28 | descriptor.script.map 29 | ) 30 | return 31 | } 32 | 33 | // styles 34 | if (query.type === `style` && query.index != null) { 35 | const style = descriptor.styles[query.index] 36 | if (appendExtension) { 37 | loaderContext.resourcePath += '.' + (style.lang || 'css') 38 | } 39 | loaderContext.callback( 40 | null, 41 | style.content, 42 | style.map 43 | ) 44 | return 45 | } 46 | 47 | // custom 48 | if (query.type === 'custom' && query.index != null) { 49 | const block = descriptor.customBlocks[query.index] 50 | loaderContext.callback( 51 | null, 52 | block.content, 53 | block.map 54 | ) 55 | return 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /third-libs/component-compiler-utils-master/lib/types.ts: -------------------------------------------------------------------------------- 1 | import { SFCDescriptor } from './parse' 2 | 3 | export interface StartOfSourceMap { 4 | file?: string 5 | sourceRoot?: string 6 | } 7 | 8 | export interface RawSourceMap extends StartOfSourceMap { 9 | version: string 10 | sources: string[] 11 | names: string[] 12 | sourcesContent?: string[] 13 | mappings: string 14 | } 15 | 16 | export interface VueTemplateCompiler { 17 | parseComponent(source: string, options?: any): SFCDescriptor 18 | 19 | compile( 20 | template: string, 21 | options: VueTemplateCompilerOptions 22 | ): VueTemplateCompilerResults 23 | 24 | ssrCompile( 25 | template: string, 26 | options: VueTemplateCompilerOptions 27 | ): VueTemplateCompilerResults 28 | } 29 | 30 | // we'll just shim this much for now - in the future these types 31 | // should come from vue-template-compiler directly, or this package should be 32 | // part of the vue monorepo. 33 | export interface VueTemplateCompilerOptions { 34 | modules?: Object[] 35 | outputSourceRange?: boolean 36 | } 37 | 38 | export interface VueTemplateCompilerParseOptions { 39 | pad?: 'line' | 'space' 40 | } 41 | 42 | export interface ErrorWithRange { 43 | msg: string 44 | start: number 45 | end: number 46 | } 47 | 48 | export interface VueTemplateCompilerResults { 49 | ast: Object | void 50 | render: string 51 | staticRenderFns: string[] 52 | errors: (string | ErrorWithRange)[] 53 | tips: (string | ErrorWithRange)[] 54 | } 55 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | :::tip VERSION NOTE 4 | This is the documentation for Vue Loader v15 and above. If you are upgrading from v14 or an earlier version, check out the [Migration Guide](./migrating.md). If you are using an older version, the old docs are [here](https://vue-loader-v14.vuejs.org). 5 | ::: 6 | 7 | ## What is Vue Loader? 8 | 9 | `vue-loader` is a loader for [webpack](https://webpack.js.org/) that allows you to author Vue components in a format called [Single-File Components (SFCs)](./spec.md): 10 | 11 | ``` vue 12 | 15 | 16 | 25 | 26 | 31 | ``` 32 | 33 | There are many cool features provided by `vue-loader`: 34 | 35 | - Allows using other webpack loaders for each part of a Vue component, for example Sass for ` 31 | ``` 32 | 33 | Использование `vue-loader` предоставляет множество интересных возможностей: 34 | 35 | - Позволяет использовать разнообразные загрузчики webpack для разных секций компонента Vue, например Sass для ` 11 | 12 | 15 | ``` 16 | 17 | 转换结果: 18 | 19 | ``` html 20 | 25 | 26 | 29 | ``` 30 | 31 | ## 混用本地和全局样式 32 | 33 | 你可以在一个组件中同时使用有 scoped 和非 scoped 样式: 34 | 35 | ``` html 36 | 39 | 40 | 43 | ``` 44 | 45 | ## 子组件的根元素 46 | 47 | 使用 `scoped` 后,父组件的样式将不会渗透到子组件中。不过一个子组件的根节点会同时受其父组件的 scoped CSS 和子组件的 scoped CSS 的影响。这样设计是为了让父组件可以从布局的角度出发,调整其子组件根元素的样式。 48 | 49 | ## 深度作用选择器 50 | 51 | 如果你希望 `scoped` 样式中的一个选择器能够作用得“更深”,例如影响子组件,你可以使用 `>>>` 操作符: 52 | 53 | ``` html 54 | 57 | ``` 58 | 59 | 上述代码将会编译成: 60 | 61 | ``` css 62 | .a[data-v-f3f3eg9] .b { /* ... */ } 63 | ``` 64 | 65 | 有些像 Sass 之类的预处理器无法正确解析 `>>>`。这种情况下你可以使用 `/deep/` 或 `::v-deep` 操作符取而代之——两者都是 `>>>` 的别名,同样可以正常工作。 66 | 67 | ## 动态生成的内容 68 | 69 | 通过 `v-html` 创建的 DOM 内容不受 scoped 样式影响,但是你仍然可以通过深度作用选择器来为他们设置样式。 70 | 71 | ## 还有一些要留意 72 | 73 | - **Scoped 样式不能代替 class**。考虑到浏览器渲染各种 CSS 选择器的方式,当 `p { color: red }` 是 scoped 时 (即与特性选择器组合使用时) 会慢很多倍。如果你使用 class 或者 id 取而代之,比如 `.example { color: red }`,性能影响就会消除。你可以在[这块试验田](https://stevesouders.com/efws/css-selectors/csscreate.php)中测试它们的不同。 74 | 75 | - **在递归组件中小心使用后代选择器!** 对选择器 `.a .b` 中的 CSS 规则来说,如果匹配 `.a` 的元素包含一个递归子组件,则所有的子组件中的 `.b` 都将被这个规则匹配。 76 | -------------------------------------------------------------------------------- /third-libs/loader-utils/parseQuery.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const JSON5 = require('json5'); 4 | 5 | const specialValues = { 6 | null: null, 7 | true: true, 8 | false: false, 9 | }; 10 | 11 | function parseQuery(query) { 12 | if (query.substr(0, 1) !== '?') { 13 | throw new Error( 14 | "A valid query string passed to parseQuery should begin with '?'" 15 | ); 16 | } 17 | 18 | query = query.substr(1); 19 | 20 | if (!query) { 21 | return {}; 22 | } 23 | 24 | // 如果是对象,则直接格式化成对象,并返回 25 | if (query.substr(0, 1) === '{' && query.substr(-1) === '}') { 26 | return JSON5.parse(query); 27 | } 28 | 29 | const queryArgs = query.split(/[,&]/g); 30 | const result = {}; 31 | 32 | queryArgs.forEach((arg) => { 33 | const idx = arg.indexOf('='); 34 | 35 | if (idx >= 0) { 36 | let name = arg.substr(0, idx); 37 | let value = decodeURIComponent(arg.substr(idx + 1)); 38 | 39 | if (specialValues.hasOwnProperty(value)) { 40 | value = specialValues[value]; 41 | } 42 | 43 | if (name.substr(-2) === '[]') { 44 | name = decodeURIComponent(name.substr(0, name.length - 2)); 45 | 46 | if (!Array.isArray(result[name])) { 47 | result[name] = []; 48 | } 49 | 50 | result[name].push(value); 51 | } else { 52 | name = decodeURIComponent(name); 53 | result[name] = value; 54 | } 55 | } else { 56 | if (arg.substr(0, 1) === '-') { 57 | result[decodeURIComponent(arg.substr(1))] = false; 58 | } else if (arg.substr(0, 1) === '+') { 59 | result[decodeURIComponent(arg.substr(1))] = true; 60 | } else { 61 | result[decodeURIComponent(arg)] = true; 62 | } 63 | } 64 | }); 65 | 66 | return result; 67 | } 68 | 69 | module.exports = parseQuery; 70 | -------------------------------------------------------------------------------- /docs/guide/extract-css.md: -------------------------------------------------------------------------------- 1 | # CSS Extraction 2 | 3 | ::: tip 4 | Only apply CSS extraction for production so that you get CSS hot reload during development. 5 | ::: 6 | 7 | ## webpack 4 8 | 9 | ``` bash 10 | npm install -D mini-css-extract-plugin 11 | ``` 12 | 13 | ``` js 14 | // webpack.config.js 15 | var MiniCssExtractPlugin = require('mini-css-extract-plugin') 16 | 17 | module.exports = { 18 | // other options... 19 | module: { 20 | rules: [ 21 | // ... other rules omitted 22 | { 23 | test: /\.css$/, 24 | use: [ 25 | process.env.NODE_ENV !== 'production' 26 | ? 'vue-style-loader' 27 | : MiniCssExtractPlugin.loader, 28 | 'css-loader' 29 | ] 30 | } 31 | ] 32 | }, 33 | plugins: [ 34 | // ... Vue Loader plugin omitted 35 | new MiniCssExtractPlugin({ 36 | filename: 'style.css' 37 | }) 38 | ] 39 | } 40 | ``` 41 | 42 | Also see [mini-css-extract-plugin docs](https://github.com/webpack-contrib/mini-css-extract-plugin). 43 | 44 | ## webpack 3 45 | 46 | ``` bash 47 | npm install -D extract-text-webpack-plugin 48 | ``` 49 | 50 | ``` js 51 | // webpack.config.js 52 | var ExtractTextPlugin = require("extract-text-webpack-plugin") 53 | 54 | module.exports = { 55 | // other options... 56 | module: { 57 | rules: [ 58 | // ... other rules omitted 59 | { 60 | test: /\.css$/, 61 | loader: ExtractTextPlugin.extract({ 62 | use: 'css-loader', 63 | fallback: 'vue-style-loader' 64 | }) 65 | } 66 | ] 67 | }, 68 | plugins: [ 69 | // ... Vue Loader plugin omitted 70 | new ExtractTextPlugin("style.css") 71 | ] 72 | } 73 | ``` 74 | 75 | Also see [extract-text-webpack-plugin docs](https://github.com/webpack-contrib/extract-text-webpack-plugin). 76 | -------------------------------------------------------------------------------- /lib/codegen/hotReload.js: -------------------------------------------------------------------------------- 1 | // 热加载利用的是vue-hot-reload-api(https://github.com/vuejs/vue-hot-reload-api) 2 | const hotReloadAPIPath = JSON.stringify(require.resolve('vue-hot-reload-api')) 3 | 4 | const genTemplateHotReloadCode = (id, request) => { 5 | return ` 6 | module.hot.accept(${request}, function () { 7 | api.rerender('${id}', { 8 | render: render, 9 | staticRenderFns: staticRenderFns 10 | }) 11 | }) 12 | `.trim() 13 | } 14 | 15 | /* 16 | zxx注: 17 | module.hot: 是webpack.hmr api(https://webpack.js.org/guides/hot-module-replacement/) 18 | 19 | api.install(require('vue')): 安装api,并告诉api我正在使用Vue,安装后会检查兼容性 20 | 21 | api.compatible: 是检查版本的兼容性 22 | 23 | module.hot.accept(): 表示此模块接受热重载 24 | 25 | api.createRecord('${id}', component.options): 为了将每一个组件中的选项变得可以热加载,需要用一个不重复的id创建一次记录,只需要在启动的时候做一次。 26 | 27 | api.${functional ? 'rerender' : 'reload'}('${id}', component.options): 28 | 如果一个组件只是修改了 template 或是 render 函数,只要把所有相关的实例重新渲染一遍就可以了,而不需要销毁重建他们。这样就可以完整的保持应用的当前状态。 29 | 这是因为template被编译成立新的无副作用的渲染函数。 30 | 31 | 如果一个组件更改了除 template或 render 之外的选项,就需要整个重新加载。这将销毁并重建整个组件(包括子组件)。 32 | 这是因为script或者custom block里可能包含带有副作用的生命周期钩子,只有重新加载才能保证组件行为的一致性。 33 | 34 | style会通过vue-style-loader自行热重载,所以它不会影响应用的状态。 35 | */ 36 | exports.genHotReloadCode = (id, functional, templateRequest) => { 37 | return ` 38 | /* hot reload */ 39 | if (module.hot) { 40 | var api = require(${hotReloadAPIPath}) 41 | api.install(require('vue')) 42 | if (api.compatible) { 43 | module.hot.accept() 44 | if (!module.hot.data) { 45 | api.createRecord('${id}', component.options) 46 | } else { 47 | api.${functional ? 'rerender' : 'reload'}('${id}', component.options) 48 | } 49 | ${templateRequest ? genTemplateHotReloadCode(id, templateRequest) : ''} 50 | } 51 | } 52 | `.trim() 53 | } 54 | -------------------------------------------------------------------------------- /third-libs/component-compiler-utils-master/lib/templateCompilerModules/utils.ts: -------------------------------------------------------------------------------- 1 | export interface Attr { 2 | name: string 3 | value: string 4 | } 5 | 6 | export interface ASTNode { 7 | tag: string 8 | attrs: Attr[] 9 | } 10 | 11 | import { UrlWithStringQuery, parse as uriParse } from 'url' 12 | 13 | export function urlToRequire(url: string): string { 14 | const returnValue = `"${url}"` 15 | // same logic as in transform-require.js 16 | const firstChar = url.charAt(0) 17 | if (firstChar === '.' || firstChar === '~' || firstChar === '@') { 18 | if (firstChar === '~') { 19 | const secondChar = url.charAt(1) 20 | url = url.slice(secondChar === '/' ? 2 : 1) 21 | } 22 | 23 | const uriParts = parseUriParts(url) 24 | 25 | if (!uriParts.hash) { 26 | return `require("${url}")` 27 | } else { 28 | // support uri fragment case by excluding it from 29 | // the require and instead appending it as string; 30 | // assuming that the path part is sufficient according to 31 | // the above caseing(t.i. no protocol-auth-host parts expected) 32 | return `require("${uriParts.path}") + "${uriParts.hash}"` 33 | } 34 | } 35 | return returnValue 36 | } 37 | 38 | /** 39 | * vuejs/component-compiler-utils#22 Support uri fragment in transformed require 40 | * @param urlString an url as a string 41 | */ 42 | function parseUriParts(urlString: string): UrlWithStringQuery { 43 | // initialize return value 44 | const returnValue: UrlWithStringQuery = uriParse('') 45 | if (urlString) { 46 | // A TypeError is thrown if urlString is not a string 47 | // @see https://nodejs.org/api/url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost 48 | if ('string' === typeof urlString) { 49 | // check is an uri 50 | return uriParse(urlString) // take apart the uri 51 | } 52 | } 53 | return returnValue 54 | } 55 | -------------------------------------------------------------------------------- /third-libs/loader-utils/stringifyRequest.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | 5 | const matchRelativePath = /^\.\.?[/\\]/; 6 | 7 | function isAbsolutePath(str) { 8 | return path.posix.isAbsolute(str) || path.win32.isAbsolute(str); 9 | } 10 | 11 | function isRelativePath(str) { 12 | return matchRelativePath.test(str); 13 | } 14 | 15 | function stringifyRequest(loaderContext, request) { 16 | const splitted = request.split('!'); 17 | const context = 18 | loaderContext.context || 19 | (loaderContext.options && loaderContext.options.context); 20 | 21 | return JSON.stringify( 22 | splitted 23 | .map((part) => { 24 | // First, separate singlePath from query, because the query might contain paths again 25 | const splittedPart = part.match(/^(.*?)(\?.*)/); 26 | const query = splittedPart ? splittedPart[2] : ''; 27 | let singlePath = splittedPart ? splittedPart[1] : part; 28 | 29 | if (isAbsolutePath(singlePath) && context) { 30 | singlePath = path.relative(context, singlePath); 31 | 32 | if (isAbsolutePath(singlePath)) { 33 | // If singlePath still matches an absolute path, singlePath was on a different drive than context. 34 | // In this case, we leave the path platform-specific without replacing any separators. 35 | // @see https://github.com/webpack/loader-utils/pull/14 36 | return singlePath + query; 37 | } 38 | 39 | if (isRelativePath(singlePath) === false) { 40 | // Ensure that the relative path starts at least with ./ otherwise it would be a request into the modules directory (like node_modules). 41 | singlePath = './' + singlePath; 42 | } 43 | } 44 | 45 | return singlePath.replace(/\\/g, '/') + query; 46 | }) 47 | .join('!') 48 | ); 49 | } 50 | 51 | module.exports = stringifyRequest; 52 | -------------------------------------------------------------------------------- /docs/ru/guide/extract-css.md: -------------------------------------------------------------------------------- 1 | # Извлечение CSS в отдельный файл 2 | 3 | ::: tip СОВЕТ 4 | Применяйте извлечение CSS в отдельный файл только в production, чтобы использовать горячую перезагрузку CSS на этапе разработки. 5 | ::: 6 | 7 | ## webpack 4 8 | 9 | ``` bash 10 | npm install -D mini-css-extract-plugin 11 | ``` 12 | 13 | ``` js 14 | // webpack.config.js 15 | var MiniCssExtractPlugin = require('mini-css-extract-plugin') 16 | 17 | module.exports = { 18 | // другие настройки... 19 | module: { 20 | rules: [ 21 | // ... другие правила опущены 22 | { 23 | test: /\.css$/, 24 | use: [ 25 | process.env.NODE_ENV !== 'production' 26 | ? 'vue-style-loader' 27 | : MiniCssExtractPlugin.loader, 28 | 'css-loader' 29 | ] 30 | } 31 | ] 32 | }, 33 | plugins: [ 34 | // ... плагин Vue Loader опущен 35 | new MiniCssExtractPlugin({ 36 | filename: 'style.css' 37 | }) 38 | ] 39 | } 40 | ``` 41 | 42 | Также смотрите [документацию mini-css-extract-plugin](https://github.com/webpack-contrib/mini-css-extract-plugin). 43 | 44 | ## webpack 3 45 | 46 | ``` bash 47 | npm install -D extract-text-webpack-plugin 48 | ``` 49 | 50 | ``` js 51 | // webpack.config.js 52 | var ExtractTextPlugin = require("extract-text-webpack-plugin") 53 | 54 | module.exports = { 55 | // другие настройки... 56 | module: { 57 | rules: [ 58 | // ... другие правила опущены 59 | { 60 | test: /\.css$/, 61 | loader: ExtractTextPlugin.extract({ 62 | use: 'css-loader', 63 | fallback: 'vue-style-loader' 64 | }) 65 | } 66 | ] 67 | }, 68 | plugins: [ 69 | // ... плагин Vue Loader опущен 70 | new ExtractTextPlugin("style.css") 71 | ] 72 | } 73 | ``` 74 | 75 | Также смотрите [документацию extract-text-webpack-plugin](https://github.com/webpack-contrib/extract-text-webpack-plugin). 76 | -------------------------------------------------------------------------------- /docs/zh/guide/custom-blocks.md: -------------------------------------------------------------------------------- 1 | # 自定义块 2 | 3 | 在 `.vue` 文件中,你可以自定义语言块。应用于一个自定义块的 loader 是基于这个块的 `lang` 特性、块的标签名以及你的 webpack 配置进行匹配的。 4 | 5 | 如果指定了一个 `lang` 特性,则这个自定义块将会作为一个带有该 `lang` 扩展名的文件进行匹配。 6 | 7 | 你也可以使用 `resourceQuery` 来为一个没有 `lang` 的自定义块匹配一条规则。例如为了匹配自定义块 ``: 8 | 9 | ``` js 10 | { 11 | module: { 12 | rules: [ 13 | { 14 | resourceQuery: /blockType=foo/, 15 | loader: 'loader-to-use' 16 | } 17 | ] 18 | } 19 | } 20 | ``` 21 | 22 | 如果找到了一个自定义块的匹配规则,它将会被处理,否则该自定义块会被默默忽略。 23 | 24 | 此外,如果这个自定义块被所有匹配的 loader 处理之后导出一个函数作为最终结果,则这个 `*.vue` 文件的组件会作为一个参数被这个函数调用。 25 | 26 | ## Example 27 | 28 | 这里有一个向组件内注入 `` 自定义块的示例,且它是在运行时可用的。 29 | 30 | 为了注入自定义块的内容,我们将会撰写一个自定义 loader: 31 | 32 | ``` js 33 | module.exports = function (source, map) { 34 | this.callback( 35 | null, 36 | `export default function (Component) { 37 | Component.options.__docs = ${ 38 | JSON.stringify(source) 39 | } 40 | }`, 41 | map 42 | ) 43 | } 44 | ``` 45 | 46 | 现在我们将会配置 webpack 来使用为 `` 自定义块撰写的自定义 loader。 47 | 48 | ``` js 49 | // wepback.config.js 50 | module.exports = { 51 | module: { 52 | rules: [ 53 | { 54 | resourceQuery: /blockType=docs/, 55 | loader: require.resolve('./docs-loader.js') 56 | } 57 | ] 58 | } 59 | } 60 | ``` 61 | 62 | 现在我们可以在运行时访问被导入组件的 `` 块内容了。 63 | 64 | ``` vue 65 | 66 | 69 | 70 | 71 | This is the documentation for component B. 72 | 73 | ``` 74 | 75 | ``` vue 76 | 77 | 83 | 84 | 96 | ``` 97 | -------------------------------------------------------------------------------- /lib/loaders/stylePostLoader.js: -------------------------------------------------------------------------------- 1 | const qs = require('querystring') 2 | // 用于处理scoped css,如果不是scoped css,则该步骤被忽略 3 | // 在css-loader之前注入 4 | /* 5 | 输入参数: 6 | interface StyleCompileOptions { 7 | source: string 8 | filename: string 9 | id: string 10 | map?: any 11 | scoped?: boolean 12 | trim?: boolean 13 | preprocessLang?: string 14 | preprocessOptions?: any 15 | postcssOptions?: any 16 | postcssPlugins?: any[] 17 | } 18 | 19 | 输出: 20 | interface StyleCompileResults { 21 | code: string 22 | map: any | void 23 | rawResult: LazyResult | void // raw lazy result from PostCSS 24 | errors: string[] 25 | } 26 | 27 | 比如:source是: 28 | 33 | 输出(只是trim了): 34 | .red { 35 | color: red; 36 | } 37 | 38 | source是: 39 | 44 | 输出(添加了data-v-): 45 | .red[data-v-27e4e96e] { 46 | color: red; 47 | } 48 | */ 49 | const { compileStyle } = require('@vue/component-compiler-utils') 50 | 51 | // This is a post loader that handles scoped CSS transforms. 52 | // Injected right before css-loader by the global pitcher (../pitch.js) 53 | // for any 11 | 12 | 15 | ``` 16 | 17 | Into the following: 18 | 19 | ``` html 20 | 25 | 26 | 29 | ``` 30 | 31 | ## Mixing Local and Global Styles 32 | 33 | You can include both scoped and non-scoped styles in the same component: 34 | 35 | ``` html 36 | 39 | 40 | 43 | ``` 44 | 45 | ## Child Component Root Elements 46 | 47 | With `scoped`, the parent component's styles will not leak into child components. However, a child component's root node will be affected by both the parent's scoped CSS and the child's scoped CSS. This is by design so that the parent can style the child root element for layout purposes. 48 | 49 | ## Deep Selectors 50 | 51 | If you want a selector in `scoped` styles to be "deep", i.e. affecting child components, you can use the `>>>` combinator: 52 | 53 | ``` html 54 | 57 | ``` 58 | 59 | The above will be compiled into: 60 | 61 | ``` css 62 | .a[data-v-f3f3eg9] .b { /* ... */ } 63 | ``` 64 | 65 | Some pre-processors, such as Sass, may not be able to parse `>>>` properly. In those cases you can use the `/deep/` or `::v-deep` combinator instead - both are aliases for `>>>` and work exactly the same. 66 | 67 | ## Dynamically Generated Content 68 | 69 | DOM content created with `v-html` are not affected by scoped styles, but you can still style them using deep selectors. 70 | 71 | ## Also Keep in Mind 72 | 73 | - **Scoped styles do not eliminate the need for classes**. Due to the way browsers render various CSS selectors, `p { color: red }` will be many times slower when scoped (i.e. when combined with an attribute selector). If you use classes or ids instead, such as in `.example { color: red }`, then you virtually eliminate that performance hit. [Here's a playground](https://stevesouders.com/efws/css-selectors/csscreate.php) where you can test the differences yourself. 74 | 75 | - **Be careful with descendant selectors in recursive components!** For a CSS rule with the selector `.a .b`, if the element that matches `.a` contains a recursive child component, then all `.b` in that child component will be matched by the rule. 76 | -------------------------------------------------------------------------------- /third-libs/querystring/decode.js: -------------------------------------------------------------------------------- 1 | // Copyright Joyent, Inc. and other Node contributors. 2 | // 3 | // Permission is hereby granted, free of charge, to any person obtaining a 4 | // copy of this software and associated documentation files (the 5 | // "Software"), to deal in the Software without restriction, including 6 | // without limitation the rights to use, copy, modify, merge, publish, 7 | // distribute, sublicense, and/or sell copies of the Software, and to permit 8 | // persons to whom the Software is furnished to do so, subject to the 9 | // following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included 12 | // in all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15 | // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 17 | // NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | // DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 20 | // USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | 'use strict'; 23 | 24 | // If obj.hasOwnProperty has been overridden, then calling 25 | // obj.hasOwnProperty(prop) will break. 26 | // See: https://github.com/joyent/node/issues/1707 27 | function hasOwnProperty(obj, prop) { 28 | return Object.prototype.hasOwnProperty.call(obj, prop); 29 | } 30 | 31 | // 对于本例子,qs=vue&type=custom&index=0&blockType=foo 32 | module.exports = function(qs, sep, eq, options) { 33 | sep = sep || '&'; 34 | eq = eq || '='; 35 | var obj = {}; 36 | 37 | if (typeof qs !== 'string' || qs.length === 0) { 38 | return obj; 39 | } 40 | 41 | var regexp = /\+/g; 42 | qs = qs.split(sep); // 对于本例子结果是:[qs=vue,type=custom,index=0,blockType=foo] 43 | 44 | var maxKeys = 1000; 45 | if (options && typeof options.maxKeys === 'number') { 46 | maxKeys = options.maxKeys; 47 | } 48 | 49 | var len = qs.length; 50 | // maxKeys <= 0 means that we should not limit keys count 51 | if (maxKeys > 0 && len > maxKeys) { 52 | len = maxKeys; 53 | } 54 | 55 | for (var i = 0; i < len; ++i) { 56 | var x = qs[i].replace(regexp, '%20'), 57 | idx = x.indexOf(eq), 58 | kstr, vstr, k, v; 59 | 60 | if (idx >= 0) { 61 | kstr = x.substr(0, idx); 62 | vstr = x.substr(idx + 1); 63 | } else { 64 | kstr = x; 65 | vstr = ''; 66 | } 67 | 68 | k = decodeURIComponent(kstr); 69 | v = decodeURIComponent(vstr); 70 | 71 | if (!hasOwnProperty(obj, k)) { 72 | obj[k] = v; 73 | } else if (Array.isArray(obj[k])) { 74 | obj[k].push(v); 75 | } else { 76 | obj[k] = [obj[k], v]; 77 | } 78 | } 79 | 80 | return obj; 81 | }; 82 | -------------------------------------------------------------------------------- /third-libs/querystring/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "_from": "querystring@0.2.0", 3 | "_id": "querystring@0.2.0", 4 | "_inBundle": false, 5 | "_integrity": "sha1-sgmEkgO7Jd+CDadW50cAWHhSFiA=", 6 | "_location": "/querystring", 7 | "_phantomChildren": {}, 8 | "_requested": { 9 | "type": "version", 10 | "registry": true, 11 | "raw": "querystring@0.2.0", 12 | "name": "querystring", 13 | "escapedName": "querystring", 14 | "rawSpec": "0.2.0", 15 | "saveSpec": null, 16 | "fetchSpec": "0.2.0" 17 | }, 18 | "_requiredBy": [ 19 | "/url" 20 | ], 21 | "_resolved": "http://registry.npm.xiaojukeji.com/querystring/download/querystring-0.2.0.tgz", 22 | "_shasum": "b209849203bb25df820da756e747005878521620", 23 | "_spec": "querystring@0.2.0", 24 | "_where": "/Users/zhangxixi/knowledge collect/vue-loader/node_modules/url", 25 | "author": { 26 | "name": "Irakli Gozalishvili", 27 | "email": "rfobic@gmail.com" 28 | }, 29 | "bugs": { 30 | "url": "http://github.com/Gozala/querystring/issues/" 31 | }, 32 | "bundleDependencies": false, 33 | "deprecated": false, 34 | "description": "Node's querystring module for all engines.", 35 | "devDependencies": { 36 | "phantomify": "~0.x.0", 37 | "retape": "~0.x.0", 38 | "tape": "~0.1.5", 39 | "test": "~0.x.0" 40 | }, 41 | "engines": { 42 | "node": ">=0.4.x" 43 | }, 44 | "homepage": "https://github.com/Gozala/querystring#readme", 45 | "id": "querystring", 46 | "keywords": [ 47 | "commonjs", 48 | "query", 49 | "querystring" 50 | ], 51 | "licenses": [ 52 | { 53 | "type": "MIT", 54 | "url": "https://github.com/Gozala/enchain/License.md" 55 | } 56 | ], 57 | "name": "querystring", 58 | "repository": { 59 | "type": "git", 60 | "url": "git://github.com/Gozala/querystring.git", 61 | "web": "https://github.com/Gozala/querystring" 62 | }, 63 | "scripts": { 64 | "test": "npm run test-node && npm run test-browser && npm run test-tap", 65 | "test-browser": "node ./node_modules/phantomify/bin/cmd.js ./test/common-index.js", 66 | "test-node": "node ./test/common-index.js", 67 | "test-tap": "node ./test/tap-index.js" 68 | }, 69 | "testling": { 70 | "files": "test/tap-index.js", 71 | "browsers": { 72 | "iexplore": [ 73 | 9, 74 | 10 75 | ], 76 | "chrome": [ 77 | 16, 78 | 20, 79 | 25, 80 | "canary" 81 | ], 82 | "firefox": [ 83 | 10, 84 | 15, 85 | 16, 86 | 17, 87 | 18, 88 | "nightly" 89 | ], 90 | "safari": [ 91 | 5, 92 | 6 93 | ], 94 | "opera": [ 95 | 12 96 | ] 97 | } 98 | }, 99 | "version": "0.2.0" 100 | } 101 | -------------------------------------------------------------------------------- /docs/guide/asset-url.md: -------------------------------------------------------------------------------- 1 | # Asset URL Handling 2 | 3 | When Vue Loader compiles the `