Last active
April 3, 2018 05:31
-
-
Save MrKou47/541a4fdd05bc8c46ec953a00e64cfeba to your computer and use it in GitHub Desktop.
dynamic以及css-loader,style-loader打包代码分析
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
webpackJsonp([0],{ | |
/***/ 9: | |
/***/ (function(module, exports, __webpack_require__) { | |
"use strict"; | |
Object.defineProperty(exports, "__esModule", { | |
value: true | |
}); | |
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | |
var _react = __webpack_require__(0); | |
var _react2 = _interopRequireDefault(_react); | |
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | |
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | |
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | |
var Dynamic = function (_React$Component) { | |
_inherits(Dynamic, _React$Component); | |
function Dynamic() { | |
_classCallCheck(this, Dynamic); | |
return _possibleConstructorReturn(this, (Dynamic.__proto__ || Object.getPrototypeOf(Dynamic)).apply(this, arguments)); | |
} | |
_createClass(Dynamic, [{ | |
key: 'render', | |
value: function render() { | |
return _react2.default.createElement( | |
'div', | |
null, | |
'i had been loaded use ', | |
_react2.default.createElement( | |
'b', | |
null, | |
'Dynamic' | |
), | |
' ', | |
_react2.default.createElement( | |
'i', | |
null, | |
'import' | |
), | |
'.' | |
); | |
} | |
}]); | |
return Dynamic; | |
}(_react2.default.Component); | |
exports.default = Dynamic; | |
/***/ }) | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function(modules) { // webpackBootstrap | |
// install a JSONP callback for chunk loading | |
var parentJsonpFunction = window["webpackJsonp"]; | |
window["webpackJsonp"] = function webpackJsonpCallback(chunkIds, moreModules, executeModules) { | |
// add "moreModules" to the modules object, | |
// then flag all "chunkIds" as loaded and fire callback | |
var moduleId, chunkId, i = 0, | |
resolves = [], | |
result; | |
for (; i < chunkIds.length; i++) { | |
chunkId = chunkIds[i]; | |
if (installedChunks[chunkId]) { | |
resolves.push(installedChunks[chunkId][0]); | |
} | |
installedChunks[chunkId] = 0; | |
} | |
for (moduleId in moreModules) { | |
if (Object.prototype.hasOwnProperty.call(moreModules, moduleId)) { | |
modules[moduleId] = moreModules[moduleId]; | |
} | |
} | |
if (parentJsonpFunction) parentJsonpFunction(chunkIds, moreModules, executeModules); | |
while (resolves.length) { | |
resolves.shift()(); | |
} | |
}; | |
// The module cache | |
var installedModules = {}; | |
// objects to store loaded and loading chunks | |
var installedChunks = { | |
1: 0 | |
}; | |
// The require function | |
function __webpack_require__(moduleId) { | |
// Check if module is in cache | |
if (installedModules[moduleId]) { | |
return installedModules[moduleId].exports; | |
} | |
// Create a new module (and put it into the cache) | |
var module = installedModules[moduleId] = { | |
i: moduleId, | |
l: false, | |
exports: {} | |
}; | |
// Execute the module function | |
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); | |
// Flag the module as loaded | |
module.l = true; | |
// Return the exports of the module | |
return module.exports; | |
} | |
// This file contains only the entry chunk. | |
// The chunk loading function for additional chunks | |
__webpack_require__.e = function requireEnsure(chunkId) { | |
var installedChunkData = installedChunks[chunkId]; | |
if (installedChunkData === 0) { | |
return new Promise(function(resolve) { resolve(); }); | |
} | |
// a Promise means "currently loading". | |
if (installedChunkData) { | |
return installedChunkData[2]; | |
} | |
// setup Promise in chunk cache | |
var promise = new Promise(function(resolve, reject) { | |
installedChunkData = installedChunks[chunkId] = [resolve, reject]; | |
}); | |
installedChunkData[2] = promise; | |
// start chunk loading | |
var head = document.getElementsByTagName('head')[0]; | |
var script = document.createElement('script'); | |
script.type = "text/javascript"; | |
script.charset = 'utf-8'; | |
script.async = true; | |
script.timeout = 120000; | |
if (__webpack_require__.nc) { | |
script.setAttribute("nonce", __webpack_require__.nc); | |
} | |
script.src = __webpack_require__.p + "" + chunkId + ".bundle.js"; | |
var timeout = setTimeout(onScriptComplete, 120000); | |
script.onerror = script.onload = onScriptComplete; | |
function onScriptComplete() { | |
// avoid mem leaks in IE. | |
script.onerror = script.onload = null; | |
clearTimeout(timeout); | |
var chunk = installedChunks[chunkId]; | |
if (chunk !== 0) { | |
if (chunk) { | |
chunk[1](new Error('Loading chunk ' + chunkId + ' failed.')); | |
} | |
installedChunks[chunkId] = undefined; | |
} | |
}; | |
head.appendChild(script); | |
return promise; | |
}; | |
// expose the modules object (__webpack_modules__) | |
__webpack_require__.m = modules; | |
// expose the module cache | |
__webpack_require__.c = installedModules; | |
// define getter function for harmony exports | |
__webpack_require__.d = function(exports, name, getter) { | |
if (!__webpack_require__.o(exports, name)) { | |
Object.defineProperty(exports, name, { | |
configurable: false, | |
enumerable: true, | |
get: getter | |
}); | |
} | |
}; | |
// getDefaultExport function for compatibility with non-harmony modules | |
__webpack_require__.n = function(module) { | |
var getter = module && module.__esModule ? | |
function getDefault() { return module['default']; } : | |
function getModuleExports() { return module; }; | |
__webpack_require__.d(getter, 'a', getter); | |
return getter; | |
}; | |
// Object.prototype.hasOwnProperty.call | |
__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); }; | |
// __webpack_public_path__ | |
__webpack_require__.p = ""; | |
// on error function for async loading | |
__webpack_require__.oe = function(err) { console.error(err); throw err; }; | |
// Load entry module and return exports | |
return __webpack_require__(__webpack_require__.s = 1); | |
}) | |
/************************************************************************/ | |
([ | |
/* 0: export React module */ | |
/***/ | |
(function(module, exports) { | |
module.exports = React; | |
/***/ | |
}), | |
/* 1: 入口文件 render.js 调用 ReactDOM.render */ | |
/***/ | |
(function(module, exports, __webpack_require__) { | |
"use strict"; | |
var _react = __webpack_require__(0); | |
var _react2 = _interopRequireDefault(_react); | |
var _reactDom = __webpack_require__(2); | |
var _reactDom2 = _interopRequireDefault(_reactDom); | |
var _App = __webpack_require__(3); | |
var _App2 = _interopRequireDefault(_App); | |
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | |
_reactDom2.default.render(_react2.default.createElement(_App2.default, null), document.getElementById('app')); | |
/***/ | |
}), | |
/* 2: export ReactDOM */ | |
/***/ | |
(function(module, exports) { | |
module.exports = ReactDOM; | |
/***/ | |
}), | |
/* 3: App.jsx 这里异步加载 Dynamic 组件 同时还 使用了 css-module */ | |
/***/ | |
(function(module, exports, __webpack_require__) { | |
"use strict"; | |
Object.defineProperty(exports, "__esModule", { | |
value: true | |
}); | |
var _createClass = function() { | |
function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; | |
descriptor.enumerable = descriptor.enumerable || false; | |
descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; | |
Object.defineProperty(target, descriptor.key, descriptor); } } return function(Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); | |
var _react = __webpack_require__(0); | |
var _react2 = _interopRequireDefault(_react); | |
var _app = __webpack_require__(4); | |
var _app2 = _interopRequireDefault(_app); | |
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } | |
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } | |
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } | |
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } | |
subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } | |
var Loader = function Loader() { | |
return _react2.default.createElement( | |
'div', | |
null, | |
'Loading' | |
); | |
}; | |
var App = function(_React$Component) { | |
_inherits(App, _React$Component); | |
function App(props) { | |
_classCallCheck(this, App); | |
var _this = _possibleConstructorReturn(this, (App.__proto__ || Object.getPrototypeOf(App)).call(this, props)); | |
_this.state = { | |
Com: Loader | |
}; | |
return _this; | |
} | |
_createClass(App, [{ | |
key: 'componentWillMount', | |
value: function componentWillMount() { | |
var _this2 = this; | |
new Promise(function(resolve) { | |
__webpack_require__.e /* require.ensure */ (0).then((function(require) { | |
resolve(__webpack_require__(9)); | |
}).bind(null, __webpack_require__)).catch(__webpack_require__.oe); | |
}).then(function(res) { | |
console.log(res.default); | |
_this2.setState({ | |
Com: res.default | |
}); | |
}); | |
} | |
}, { | |
key: 'render', | |
value: function render() { | |
var Com = this.state.Com; | |
return _react2.default.createElement( | |
'div', | |
null, | |
_react2.default.createElement( | |
'p', { className: _app2.default.red }, | |
'hello world' | |
), | |
_react2.default.createElement(Com, null) | |
); | |
} | |
}]); | |
return App; | |
}(_react2.default.Component); | |
; | |
exports.default = App; | |
/***/ | |
}), | |
/* 4: 格式化 css-loader 模块生成的描述css的对象 添加 module.hot 然后暴露出去 */ | |
/***/ | |
(function(module, exports, __webpack_require__) { | |
var content = __webpack_require__(5); | |
if (typeof content === 'string') content = [ | |
[module.i, content, ''] | |
]; | |
var transform; | |
var insertInto; | |
var options = { "hmr": true } | |
options.transform = transform | |
options.insertInto = undefined; | |
var update = __webpack_require__(7)(content, options); | |
if (content.locals) module.exports = content.locals; | |
if (false) { | |
module.hot.accept("!!../node_modules/css-loader/index.js?modules&localIdentName=[name]---[local]---[hash:base64:5]!./app.css", function() { | |
var newContent = require("!!../node_modules/css-loader/index.js?modules&localIdentName=[name]---[local]---[hash:base64:5]!./app.css"); | |
if (typeof newContent === 'string') newContent = [ | |
[module.id, newContent, ''] | |
]; | |
var locals = (function(a, b) { | |
var key, idx = 0; | |
for (key in a) { | |
if (!b || a[key] !== b[key]) return false; | |
idx++; | |
} | |
for (key in b) idx--; | |
return idx === 0; | |
}(content.locals, newContent.locals)); | |
if (!locals) throw new Error('Aborting CSS HMR due to changed css-modules locals.'); | |
update(newContent); | |
}); | |
module.hot.dispose(function() { update(); }); | |
} | |
/***/ | |
}), | |
/* 5 css-loader 最后暴露出的css对象 */ | |
/***/ | |
(function(module, exports, __webpack_require__) { | |
exports = module.exports = __webpack_require__(6)(false); | |
// imports | |
// module | |
exports.push([module.i, ".app---red---qrmPo {\n color: red;\n}", ""]); | |
// exports | |
exports.locals = { | |
"red": "app---red---qrmPo" | |
}; | |
/***/ | |
}), | |
/* 6 css-loader 的基础实现 */ | |
/***/ | |
(function(module, exports, __webpack_require__) { | |
"use strict"; | |
/* | |
MIT License http://www.opensource.org/licenses/mit-license.php | |
Author Tobias Koppers @sokra | |
*/ | |
// css base code, injected by the css-loader | |
module.exports = function(useSourceMap) { | |
var list = []; | |
// return the list of modules as css string | |
list.toString = function toString() { | |
return this.map(function(item) { | |
var content = cssWithMappingToString(item, useSourceMap); | |
if (item[2]) { | |
return "@media " + item[2] + "{" + content + "}"; | |
} else { | |
return content; | |
} | |
}).join(""); | |
}; | |
// import a list of modules into the list | |
list.i = function(modules, mediaQuery) { | |
if (typeof modules === "string") modules = [ | |
[null, modules, ""] | |
]; | |
var alreadyImportedModules = {}; | |
for (var i = 0; i < this.length; i++) { | |
var id = this[i][0]; | |
if (typeof id === "number") alreadyImportedModules[id] = true; | |
} | |
for (i = 0; i < modules.length; i++) { | |
var item = modules[i]; | |
// skip already imported module | |
// this implementation is not 100% perfect for weird media query combinations | |
// when a module is imported multiple times with different media queries. | |
// I hope this will never occur (Hey this way we have smaller bundles) | |
if (typeof item[0] !== "number" || !alreadyImportedModules[item[0]]) { | |
if (mediaQuery && !item[2]) { | |
item[2] = mediaQuery; | |
} else if (mediaQuery) { | |
item[2] = "(" + item[2] + ") and (" + mediaQuery + ")"; | |
} | |
list.push(item); | |
} | |
} | |
}; | |
return list; | |
}; | |
function cssWithMappingToString(item, useSourceMap) { | |
var content = item[1] || ''; | |
var cssMapping = item[3]; | |
if (!cssMapping) { | |
return content; | |
} | |
if (useSourceMap && typeof btoa === 'function') { | |
var sourceMapping = toComment(cssMapping); | |
var sourceURLs = cssMapping.sources.map(function(source) { | |
return '/*# sourceURL=' + cssMapping.sourceRoot + source + ' */'; | |
}); | |
return [content].concat(sourceURLs).concat([sourceMapping]).join('\n'); | |
} | |
return [content].join('\n'); | |
} | |
// Adapted from convert-source-map (MIT) | |
function toComment(sourceMap) { | |
// eslint-disable-next-line no-undef | |
var base64 = btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))); | |
var data = 'sourceMappingURL=data:application/json;charset=utf-8;base64,' + base64; | |
return '/*# ' + data + ' */'; | |
} | |
/***/ | |
}), | |
/* 7 style-loader 的实现 功能是解析 css-loader 生成的对象 将制定的内容插入到 <head> 中 */ | |
/***/ | |
(function(module, exports, __webpack_require__) { | |
/* | |
MIT License http://www.opensource.org/licenses/mit-license.php | |
Author Tobias Koppers @sokra | |
*/ | |
var stylesInDom = {}; | |
var memoize = function(fn) { | |
var memo; | |
return function() { | |
if (typeof memo === "undefined") memo = fn.apply(this, arguments); | |
return memo; | |
}; | |
}; | |
var isOldIE = memoize(function() { | |
// Test for IE <= 9 as proposed by Browserhacks | |
// @see http://browserhacks.com/#hack-e71d8692f65334173fee715c222cb805 | |
// Tests for existence of standard globals is to allow style-loader | |
// to operate correctly into non-standard environments | |
// @see https://github.com/webpack-contrib/style-loader/issues/177 | |
return window && document && document.all && !window.atob; | |
}); | |
var getTarget = function(target) { | |
return document.querySelector(target); | |
}; | |
var getElement = (function(fn) { | |
var memo = {}; | |
return function(target) { | |
// If passing function in options, then use it for resolve "head" element. | |
// Useful for Shadow Root style i.e | |
// { | |
// insertInto: function () { return document.querySelector("#foo").shadowRoot } | |
// } | |
if (typeof target === 'function') { | |
return target(); | |
} | |
if (typeof memo[target] === "undefined") { | |
var styleTarget = getTarget.call(this, target); | |
// Special case to return head of iframe instead of iframe itself | |
if (window.HTMLIFrameElement && styleTarget instanceof window.HTMLIFrameElement) { | |
try { | |
// This will throw an exception if access to iframe is blocked | |
// due to cross-origin restrictions | |
styleTarget = styleTarget.contentDocument.head; | |
} catch (e) { | |
styleTarget = null; | |
} | |
} | |
memo[target] = styleTarget; | |
} | |
return memo[target] | |
}; | |
})(); | |
var singleton = null; | |
var singletonCounter = 0; | |
var stylesInsertedAtTop = []; | |
var fixUrls = __webpack_require__(8); | |
module.exports = function(list, options) { | |
if (typeof DEBUG !== "undefined" && DEBUG) { | |
if (typeof document !== "object") throw new Error("The style-loader cannot be used in a non-browser environment"); | |
} | |
options = options || {}; | |
options.attrs = typeof options.attrs === "object" ? options.attrs : {}; | |
// Force single-tag solution on IE6-9, which has a hard limit on the # of <style> | |
// tags it will allow on a page | |
if (!options.singleton && typeof options.singleton !== "boolean") options.singleton = isOldIE(); | |
// By default, add <style> tags to the <head> element | |
if (!options.insertInto) options.insertInto = "head"; | |
// By default, add <style> tags to the bottom of the target | |
if (!options.insertAt) options.insertAt = "bottom"; | |
var styles = listToStyles(list, options); | |
addStylesToDom(styles, options); | |
return function update(newList) { | |
var mayRemove = []; | |
for (var i = 0; i < styles.length; i++) { | |
var item = styles[i]; | |
var domStyle = stylesInDom[item.id]; | |
domStyle.refs--; | |
mayRemove.push(domStyle); | |
} | |
if (newList) { | |
var newStyles = listToStyles(newList, options); | |
addStylesToDom(newStyles, options); | |
} | |
for (var i = 0; i < mayRemove.length; i++) { | |
var domStyle = mayRemove[i]; | |
if (domStyle.refs === 0) { | |
for (var j = 0; j < domStyle.parts.length; j++) domStyle.parts[j](); | |
delete stylesInDom[domStyle.id]; | |
} | |
} | |
}; | |
}; | |
function addStylesToDom(styles, options) { | |
for (var i = 0; i < styles.length; i++) { | |
var item = styles[i]; | |
var domStyle = stylesInDom[item.id]; | |
if (domStyle) { | |
domStyle.refs++; | |
for (var j = 0; j < domStyle.parts.length; j++) { | |
domStyle.parts[j](item.parts[j]); | |
} | |
for (; j < item.parts.length; j++) { | |
domStyle.parts.push(addStyle(item.parts[j], options)); | |
} | |
} else { | |
var parts = []; | |
for (var j = 0; j < item.parts.length; j++) { | |
parts.push(addStyle(item.parts[j], options)); | |
} | |
stylesInDom[item.id] = { id: item.id, refs: 1, parts: parts }; | |
} | |
} | |
} | |
function listToStyles(list, options) { | |
var styles = []; | |
var newStyles = {}; | |
for (var i = 0; i < list.length; i++) { | |
var item = list[i]; | |
var id = options.base ? item[0] + options.base : item[0]; | |
var css = item[1]; | |
var media = item[2]; | |
var sourceMap = item[3]; | |
var part = { css: css, media: media, sourceMap: sourceMap }; | |
if (!newStyles[id]) styles.push(newStyles[id] = { id: id, parts: [part] }); | |
else newStyles[id].parts.push(part); | |
} | |
return styles; | |
} | |
function insertStyleElement(options, style) { | |
var target = getElement(options.insertInto) | |
if (!target) { | |
throw new Error("Couldn't find a style target. This probably means that the value for the 'insertInto' parameter is invalid."); | |
} | |
var lastStyleElementInsertedAtTop = stylesInsertedAtTop[stylesInsertedAtTop.length - 1]; | |
if (options.insertAt === "top") { | |
if (!lastStyleElementInsertedAtTop) { | |
target.insertBefore(style, target.firstChild); | |
} else if (lastStyleElementInsertedAtTop.nextSibling) { | |
target.insertBefore(style, lastStyleElementInsertedAtTop.nextSibling); | |
} else { | |
target.appendChild(style); | |
} | |
stylesInsertedAtTop.push(style); | |
} else if (options.insertAt === "bottom") { | |
target.appendChild(style); | |
} else if (typeof options.insertAt === "object" && options.insertAt.before) { | |
var nextSibling = getElement(options.insertInto + " " + options.insertAt.before); | |
target.insertBefore(style, nextSibling); | |
} else { | |
throw new Error("[Style Loader]\n\n Invalid value for parameter 'insertAt' ('options.insertAt') found.\n Must be 'top', 'bottom', or Object.\n (https://github.com/webpack-contrib/style-loader#insertat)\n"); | |
} | |
} | |
function removeStyleElement(style) { | |
if (style.parentNode === null) return false; | |
style.parentNode.removeChild(style); | |
var idx = stylesInsertedAtTop.indexOf(style); | |
if (idx >= 0) { | |
stylesInsertedAtTop.splice(idx, 1); | |
} | |
} | |
function createStyleElement(options) { | |
var style = document.createElement("style"); | |
options.attrs.type = "text/css"; | |
addAttrs(style, options.attrs); | |
insertStyleElement(options, style); | |
return style; | |
} | |
function createLinkElement(options) { | |
var link = document.createElement("link"); | |
options.attrs.type = "text/css"; | |
options.attrs.rel = "stylesheet"; | |
addAttrs(link, options.attrs); | |
insertStyleElement(options, link); | |
return link; | |
} | |
function addAttrs(el, attrs) { | |
Object.keys(attrs).forEach(function(key) { | |
el.setAttribute(key, attrs[key]); | |
}); | |
} | |
function addStyle(obj, options) { | |
var style, update, remove, result; | |
// If a transform function was defined, run it on the css | |
if (options.transform && obj.css) { | |
result = options.transform(obj.css); | |
if (result) { | |
// If transform returns a value, use that instead of the original css. | |
// This allows running runtime transformations on the css. | |
obj.css = result; | |
} else { | |
// If the transform function returns a falsy value, don't add this css. | |
// This allows conditional loading of css | |
return function() { | |
// noop | |
}; | |
} | |
} | |
if (options.singleton) { | |
var styleIndex = singletonCounter++; | |
style = singleton || (singleton = createStyleElement(options)); | |
update = applyToSingletonTag.bind(null, style, styleIndex, false); | |
remove = applyToSingletonTag.bind(null, style, styleIndex, true); | |
} else if ( | |
obj.sourceMap && | |
typeof URL === "function" && | |
typeof URL.createObjectURL === "function" && | |
typeof URL.revokeObjectURL === "function" && | |
typeof Blob === "function" && | |
typeof btoa === "function" | |
) { | |
style = createLinkElement(options); | |
update = updateLink.bind(null, style, options); | |
remove = function() { | |
removeStyleElement(style); | |
if (style.href) URL.revokeObjectURL(style.href); | |
}; | |
} else { | |
style = createStyleElement(options); | |
update = applyToTag.bind(null, style); | |
remove = function() { | |
removeStyleElement(style); | |
}; | |
} | |
update(obj); | |
return function updateStyle(newObj) { | |
if (newObj) { | |
if ( | |
newObj.css === obj.css && | |
newObj.media === obj.media && | |
newObj.sourceMap === obj.sourceMap | |
) { | |
return; | |
} | |
update(obj = newObj); | |
} else { | |
remove(); | |
} | |
}; | |
} | |
var replaceText = (function() { | |
var textStore = []; | |
return function(index, replacement) { | |
textStore[index] = replacement; | |
return textStore.filter(Boolean).join('\n'); | |
}; | |
})(); | |
function applyToSingletonTag(style, index, remove, obj) { | |
var css = remove ? "" : obj.css; | |
if (style.styleSheet) { | |
style.styleSheet.cssText = replaceText(index, css); | |
} else { | |
var cssNode = document.createTextNode(css); | |
var childNodes = style.childNodes; | |
if (childNodes[index]) style.removeChild(childNodes[index]); | |
if (childNodes.length) { | |
style.insertBefore(cssNode, childNodes[index]); | |
} else { | |
style.appendChild(cssNode); | |
} | |
} | |
} | |
function applyToTag(style, obj) { | |
var css = obj.css; | |
var media = obj.media; | |
if (media) { | |
style.setAttribute("media", media) | |
} | |
if (style.styleSheet) { | |
style.styleSheet.cssText = css; | |
} else { | |
while (style.firstChild) { | |
style.removeChild(style.firstChild); | |
} | |
style.appendChild(document.createTextNode(css)); | |
} | |
} | |
function updateLink(link, options, obj) { | |
var css = obj.css; | |
var sourceMap = obj.sourceMap; | |
/* | |
If convertToAbsoluteUrls isn't defined, but sourcemaps are enabled | |
and there is no publicPath defined then lets turn convertToAbsoluteUrls | |
on by default. Otherwise default to the convertToAbsoluteUrls option | |
directly | |
*/ | |
var autoFixUrls = options.convertToAbsoluteUrls === undefined && sourceMap; | |
if (options.convertToAbsoluteUrls || autoFixUrls) { | |
css = fixUrls(css); | |
} | |
if (sourceMap) { | |
// http://stackoverflow.com/a/26603875 | |
css += "\n/*# sourceMappingURL=data:application/json;base64," + btoa(unescape(encodeURIComponent(JSON.stringify(sourceMap)))) + " */"; | |
} | |
var blob = new Blob([css], { type: "text/css" }); | |
var oldSrc = link.href; | |
link.href = URL.createObjectURL(blob); | |
if (oldSrc) URL.revokeObjectURL(oldSrc); | |
} | |
/***/ | |
}), | |
/* 8 sourceMap 的支持 */ | |
/***/ | |
(function(module, exports, __webpack_require__) { | |
"use strict"; | |
/** | |
* When source maps are enabled, `style-loader` uses a link element with a data-uri to | |
* embed the css on the page. This breaks all relative urls because now they are relative to a | |
* bundle instead of the current page. | |
* | |
* One solution is to only use full urls, but that may be impossible. | |
* | |
* Instead, this function "fixes" the relative urls to be absolute according to the current page location. | |
* | |
* A rudimentary test suite is located at `test/fixUrls.js` and can be run via the `npm test` command. | |
* | |
*/ | |
module.exports = function(css) { | |
// get current location | |
var location = typeof window !== "undefined" && window.location; | |
if (!location) { | |
throw new Error("fixUrls requires window.location"); | |
} | |
// blank or null? | |
if (!css || typeof css !== "string") { | |
return css; | |
} | |
var baseUrl = location.protocol + "//" + location.host; | |
var currentDir = baseUrl + location.pathname.replace(/\/[^\/]*$/, "/"); | |
// convert each url(...) | |
var fixedCss = css.replace(/url\s*\(((?:[^)(]|\((?:[^)(]+|\([^)(]*\))*\))*)\)/gi, function(fullMatch, origUrl) { | |
// strip quotes (if they exist) | |
var unquotedOrigUrl = origUrl.trim().replace(/^"(.*)"$/, function(o, $1) { | |
return $1; | |
}).replace(/^'(.*)'$/, function(o, $1) { | |
return $1; | |
}); | |
// already a full url? no change | |
if (/^(#|data:|http:\/\/|https:\/\/|file:\/\/\/|\s*$)/i.test(unquotedOrigUrl)) { | |
return fullMatch; | |
} | |
// convert the url to a full url | |
var newUrl; | |
if (unquotedOrigUrl.indexOf("//") === 0) { | |
//TODO: should we add protocol? | |
newUrl = unquotedOrigUrl; | |
} else if (unquotedOrigUrl.indexOf("/") === 0) { | |
// path should be relative to the base url | |
newUrl = baseUrl + unquotedOrigUrl; // already starts with '/' | |
} else { | |
// path should be relative to current directory | |
newUrl = currentDir + unquotedOrigUrl.replace(/^\.\//, ""); // Strip leading './' | |
} | |
// send back the fixed url(...) | |
return "url(" + JSON.stringify(newUrl) + ")"; | |
}); | |
// send back the fixed css | |
return fixedCss; | |
}; | |
/***/ | |
}) | |
]); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment