Skip to content

Commit

Permalink
Vue-loader-v15.7.0
Browse files Browse the repository at this point in the history
  • Loading branch information
yzsunlei committed Dec 15, 2019
1 parent 6102e64 commit 140a87e
Show file tree
Hide file tree
Showing 95 changed files with 3,542 additions and 0 deletions.
7 changes: 7 additions & 0 deletions 5.Vue-loader/example/debugger.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = function (...args) {
this.callback(null, ...args)
}

module.exports.pitch = function (request) {
// debug
}
2 changes: 2 additions & 0 deletions 5.Vue-loader/example/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<div id="app"></div>
<script src="/dist/bundle.js"></script>
7 changes: 7 additions & 0 deletions 5.Vue-loader/example/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import Vue from 'vue'
import Foo from './source.vue'

new Vue({
el: '#app',
render: h => h(Foo)
})
26 changes: 26 additions & 0 deletions 5.Vue-loader/example/source.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<template lang="pug">
div(ok)
h1(:class="$style.red") hello
</template>

<script>
export default {
data () {
return {
msg: 'fesfff'
}
}
}
</script>

<style module>
.red {
color: red;
}
</style>

<foo>
export default comp => {
console.log(comp.options.data())
}
</foo>
2 changes: 2 additions & 0 deletions 5.Vue-loader/example/test.pug
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
div(ok)
h1(:class="$style.red") hello
97 changes: 97 additions & 0 deletions 5.Vue-loader/example/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
const path = require('path')
const VueLoaderPlugin = require('../lib/plugin')

module.exports = {
mode: 'development',
entry: path.resolve(__dirname, './main.js'),
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/dist/'
},
devServer: {
stats: "minimal",
contentBase: __dirname
},
module: {
rules: [
// { loader: require.resolve('./debugger') },
{
test: /\.vue$/,
loader: 'vue-loader'
},
// example to apply loader to a custom block without lang="xxx"
// this rule applies to <foo> blocks
{
resourceQuery: /blockType=foo/,
loader: 'babel-loader'
},
// example configuring preprocessor for <template lang="pug">
{
test: /\.pug$/,
oneOf: [
// this applies to <template lang="pug"> in Vue components
{
resourceQuery: /^\?vue/,
use: ['pug-plain-loader']
},
// this applies to pug imports inside JavaScript
{
use: ['raw-loader', 'pug-plain-loader']
}
]
},
// example configuring CSS Modules
{
test: /\.css$/,
oneOf: [
// this applies to <style module>
{
resourceQuery: /module/,
use: [
'vue-style-loader',
{
loader: 'css-loader',
options: {
modules: true,
localIdentName: '[local]_[hash:base64:8]'
}
}
]
},
// this applies to <style> or <style scoped>
{
use: [
'vue-style-loader',
'css-loader'
]
}
]
},
// exmaple configration for <style lang="scss">
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
{
loader: 'sass-loader',
// global data for all components
// this can be read from a scss file
options: {
data: '$color: red;'
}
}
]
}
]
},
resolveLoader: {
alias: {
'vue-loader': require.resolve('../lib')
}
},
plugins: [
new VueLoaderPlugin()
]
}
21 changes: 21 additions & 0 deletions 5.Vue-loader/lib/codegen/customBlocks.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
const qs = require('querystring')
const { attrsToQuery } = require('./utils')

module.exports = function genCustomBlocksCode (
blocks,
resourcePath,
resourceQuery,
stringifyRequest
) {
return `\n/* custom blocks */\n` + blocks.map((block, i) => {
const src = block.attrs.src || resourcePath
const attrsQuery = attrsToQuery(block.attrs)
const issuerQuery = block.attrs.src ? `&issuerPath=${qs.escape(resourcePath)}` : ''
const inheritQuery = resourceQuery ? `&${resourceQuery.slice(1)}` : ''
const query = `?vue&type=custom&index=${i}&blockType=${qs.escape(block.type)}${issuerQuery}${attrsQuery}${inheritQuery}`
return (
`import block${i} from ${stringifyRequest(src + query)}\n` +
`if (typeof block${i} === 'function') block${i}(component)`
)
}).join(`\n`) + `\n`
}
31 changes: 31 additions & 0 deletions 5.Vue-loader/lib/codegen/hotReload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
const hotReloadAPIPath = JSON.stringify(require.resolve('vue-hot-reload-api'))

const genTemplateHotReloadCode = (id, request) => {
return `
module.hot.accept(${request}, function () {
api.rerender('${id}', {
render: render,
staticRenderFns: staticRenderFns
})
})
`.trim()
}

exports.genHotReloadCode = (id, functional, templateRequest) => {
return `
/* hot reload */
if (module.hot) {
var api = require(${hotReloadAPIPath})
api.install(require('vue'))
if (api.compatible) {
module.hot.accept()
if (!module.hot.data) {
api.createRecord('${id}', component.options)
} else {
api.${functional ? 'rerender' : 'reload'}('${id}', component.options)
}
${templateRequest ? genTemplateHotReloadCode(id, templateRequest) : ''}
}
}
`.trim()
}
123 changes: 123 additions & 0 deletions 5.Vue-loader/lib/codegen/styleInjection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
const { attrsToQuery } = require('./utils')
const hotReloadAPIPath = JSON.stringify(require.resolve('vue-hot-reload-api'))
const nonWhitespaceRE = /\S+/

module.exports = function genStyleInjectionCode (
loaderContext,
styles,
id,
resourcePath,
stringifyRequest,
needsHotReload,
needsExplicitInjection
) {
let styleImportsCode = ``
let styleInjectionCode = ``
let cssModulesHotReloadCode = ``

let hasCSSModules = false
const cssModuleNames = new Map()

function genStyleRequest (style, i) {
const src = style.src || resourcePath
const attrsQuery = attrsToQuery(style.attrs, 'css')
const inheritQuery = `&${loaderContext.resourceQuery.slice(1)}`
// make sure to only pass id when necessary so that we don't inject
// duplicate tags when multiple components import the same css file
const idQuery = style.scoped ? `&id=${id}` : ``
const query = `?vue&type=style&index=${i}${idQuery}${attrsQuery}${inheritQuery}`
return stringifyRequest(src + query)
}

function genCSSModulesCode (style, request, i) {
hasCSSModules = true

const moduleName = style.module === true ? '$style' : style.module
if (cssModuleNames.has(moduleName)) {
loaderContext.emitError(`CSS module name ${moduleName} is not unique!`)
}
cssModuleNames.set(moduleName, true)

// `(vue-)style-loader` exports the name-to-hash map directly
// `css-loader` exports it in `.locals`
const locals = `(style${i}.locals || style${i})`
const name = JSON.stringify(moduleName)

if (!needsHotReload) {
styleInjectionCode += `this[${name}] = ${locals}\n`
} else {
styleInjectionCode += `
cssModules[${name}] = ${locals}
Object.defineProperty(this, ${name}, {
configurable: true,
get: function () {
return cssModules[${name}]
}
})
`
cssModulesHotReloadCode += `
module.hot && module.hot.accept([${request}], function () {
var oldLocals = cssModules[${name}]
if (oldLocals) {
var newLocals = require(${request})
if (JSON.stringify(newLocals) !== JSON.stringify(oldLocals)) {
cssModules[${name}] = newLocals
require(${hotReloadAPIPath}).rerender("${id}")
}
}
})
`
}
}

// empty styles: with no `src` specified or only contains whitespaces
const isNotEmptyStyle = style => style.src || nonWhitespaceRE.test(style.content)
// explicit injection is needed in SSR (for critical CSS collection)
// or in Shadow Mode (for injection into shadow root)
// In these modes, vue-style-loader exports objects with the __inject__
// method; otherwise we simply import the styles.
if (!needsExplicitInjection) {
styles.forEach((style, i) => {
// do not generate requests for empty styles
if (isNotEmptyStyle(style)) {
const request = genStyleRequest(style, i)
styleImportsCode += `import style${i} from ${request}\n`
if (style.module) genCSSModulesCode(style, request, i)
}
})
} else {
styles.forEach((style, i) => {
if (isNotEmptyStyle(style)) {
const request = genStyleRequest(style, i)
styleInjectionCode += (
`var style${i} = require(${request})\n` +
`if (style${i}.__inject__) style${i}.__inject__(context)\n`
)
if (style.module) genCSSModulesCode(style, request, i)
}
})
}

if (!needsExplicitInjection && !hasCSSModules) {
return styleImportsCode
}

return `
${styleImportsCode}
${hasCSSModules && needsHotReload ? `var cssModules = {}` : ``}
${needsHotReload ? `var disposed = false` : ``}
function injectStyles (context) {
${needsHotReload ? `if (disposed) return` : ``}
${styleInjectionCode}
}
${needsHotReload ? `
module.hot && module.hot.dispose(function (data) {
disposed = true
})
` : ``}
${cssModulesHotReloadCode}
`.trim()
}
25 changes: 25 additions & 0 deletions 5.Vue-loader/lib/codegen/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
const qs = require('querystring')

// these are built-in query parameters so should be ignored
// if the user happen to add them as attrs
const ignoreList = [
'id',
'index',
'src',
'type'
]

// transform the attrs on a SFC block descriptor into a resourceQuery string
exports.attrsToQuery = (attrs, langFallback) => {
let query = ``
for (const name in attrs) {
const value = attrs[name]
if (!ignoreList.includes(name)) {
query += `&${qs.escape(name)}=${value ? qs.escape(value) : ``}`
}
}
if (langFallback && !(`lang` in attrs)) {
query += `&lang=${langFallback}`
}
return query
}
7 changes: 7 additions & 0 deletions 5.Vue-loader/lib/index.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { Plugin } from 'webpack'

declare namespace VueLoader {
class VueLoaderPlugin extends Plugin {}
}

export = VueLoader
Loading

0 comments on commit 140a87e

Please sign in to comment.