Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 35 additions & 4 deletions plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ var parseOpts = {
var runtimePath = require.resolve('./browser')
// Used to tag nodes that are splitRequire() calls.
var kIsSplitRequireCall = Symbol('is split-require call')
var kIsBoundSrCall = Symbol('is bound split-require call')

function mayContainSplitRequire (str) {
return str.includes('split-require')
Expand Down Expand Up @@ -49,6 +50,13 @@ function createSplitRequireDetector () {
if (node.type === 'CallExpression' && node.callee.type === 'Identifier' && check(node.callee.name)) {
node[kIsSplitRequireCall] = true
}
// var sr = require('split-require'); var load = sr.bind(null, './xyz')
if (node.type === 'CallExpression' &&
node.callee.type === 'MemberExpression' &&
node.callee.object.type === 'Identifier' && check(node.callee.object.name) &&
node.callee.property.type === 'Identifier' && node.callee.property.name === 'bind') {
node[kIsBoundSrCall] = true
}
return false
}

Expand Down Expand Up @@ -84,6 +92,11 @@ function transformSplitRequireCalls (file, opts) {
arg.edit.prepend('require(').append(')')
hasSplitRequireCall = true
}
if (node[kIsBoundSrCall]) {
var arg = node.arguments[1] // eslint-disable-line no-redeclare
arg.edit.prepend('require(').append(')')
hasSplitRequireCall = true
}
})

// Pass through unchanged.
Expand Down Expand Up @@ -143,6 +156,9 @@ function createSplitter (b, opts) {
if (node[kIsSplitRequireCall]) {
processSplitRequire(row, node)
}
if (node[kIsBoundSrCall]) {
processBoundSplitRequire(row, node)
}
})

row.transformable = result
Expand Down Expand Up @@ -196,10 +212,13 @@ function createSplitter (b, opts) {
if (mainRows.includes(depEntry.id)) {
// this entry point is also non-dynamically required by the main bundle.
// we should not move it into a dynamic bundle.
node.callee.edit.append('.t')
// wrap this in a closure so we call `require()` asynchronously,
// just like if it was actually dynamically loaded
node.arguments[0].edit.prepend('function(){return require(').append(')}')
if (node[kIsBoundSrCall]) {
node.callee.object.edit.append('.t')
node.arguments[1].edit.prepend('function(){return require(').append(')}')
} else {
node.callee.edit.append('.t')
node.arguments[0].edit.prepend('function(){return require(').append(')}')
}

// add the dependency back
row.deps[depEntry.id] = depEntry.id
Expand Down Expand Up @@ -337,6 +356,18 @@ function createSplitter (b, opts) {
queueSplitRequire(row.id, resolved, node)
}

function processBoundSplitRequire (row, node) {
var requirePath = node.arguments[1].arguments[0].value
var resolved = row.deps[requirePath]
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can also use this code for sr.call(null, 'whatever'), i think.

if (resolved == null) {
resolved = requirePath
}

node.arguments[1].edit.update(JSON.stringify(resolved))

queueSplitRequire(row.id, resolved, node)
}

function getRow (id) {
return rowsById[id]
}
Expand Down
8 changes: 8 additions & 0 deletions test/bound/app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
var sr = require('split-require')

var load1 = sr.bind(null, './one')
var load2 = sr.bind(null, './two')

load1(function () {
load2(function () {})
})
6 changes: 6 additions & 0 deletions test/bound/expected/bundle.2.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"entry2":[function(require,module,exports){
require("split-require").l(2, require("a"));
},{"a":2,"split-require":"split-require"}],2:[function(require,module,exports){
module.exports = 'one'

},{}]},{},["entry2"]);
6 changes: 6 additions & 0 deletions test/bound/expected/bundle.3.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"entry3":[function(require,module,exports){
require("split-require").l(3, require("a"));
},{"a":3,"split-require":"split-require"}],3:[function(require,module,exports){
module.exports = 'two'

},{}]},{},["entry3"]);
86 changes: 86 additions & 0 deletions test/bound/expected/bundle.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
require=(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({"split_require_mappings":[function(require,module,exports){
require("split-require").b = {"2":"bundle.2.js","3":"bundle.3.js"};
},{"split-require":"split-require"}],1:[function(require,module,exports){
var sr = require('split-require')

var load1 = sr.bind(null, 2)
var load2 = sr.bind(null, 3)

load1(function () {
load2(function () {})
})

},{"split-require":"split-require"}],"split-require":[function(require,module,exports){
// Store dynamic bundle exports.
var cache = {}
// Store dynamic bundle loading callbacks, in case the same module is imported
// multiple times simultaneously.
var receivers = {}

function load (index, cb) {
// We already have this bundle.
if (cache[index]) {
if (cb) setTimeout(cb.bind(null, null, cache[index]), 0)
return
}

var url = load.b[index]
// TODO throw an error if we don't have the url

// Combine callbacks if another one was already registered.
var prev = receivers[index]
receivers[index] = onload

function onload (err, result) {
if (prev) prev(err, result)
else if (!err) cache[index] = result
if (cb) cb(err, result)
delete receivers[index]
}

// The <script> element for this bundle was already added.
if (prev) return

var s = document.createElement('script')
s.async = true
s.type = 'application/javascript'
s.src = url
s.onerror = function () {
onload(Error('Failed to load'))
}
document.body.appendChild(s)
}

// Called by dynamic bundles once they have loaded.
function loadedBundle (index, result) {
if (receivers[index]) {
receivers[index](null, result)
} else {
cache[index] = result
}
}

// "Load" a module that we know is included in this bundle.
var nextTick = window.setImmediate || window.setTimeout
function loadLocal (requirer, onload) {
nextTick(function () {
// Just execute the module if no callback is provided
if (!onload) return requirer()
try {
onload(null, requirer())
} catch (err) {
onload(err)
}
})
}

// Map dynamic bundle entry point IDs to URLs.
load.b = {}

// Used by the bundle.
load.l = loadedBundle
load.t = loadLocal

module.exports = load

},{}]},{},["split_require_mappings",1]);
1 change: 1 addition & 0 deletions test/bound/one.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'one'
1 change: 1 addition & 0 deletions test/bound/two.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = 'two'