This commit is contained in:
darenhsu
2022-07-17 13:16:16 +08:00
parent 84759556ff
commit befd344ab0
28070 changed files with 4008428 additions and 1 deletions
+27
View File
@@ -0,0 +1,27 @@
BSD 3-Clause License
---------------
Copyright © 2018 Zackary Jackson All rights reserved.
Copyright © 2018 ScriptedAlchemy LLC All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or
other materials provided with the distribution.
* Neither the name of “ScriptedAlchemy” nor the names of its contributors may be used to
endorse or promote products derived from this software without specific prior
written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS” AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+491
View File
@@ -0,0 +1,491 @@
# Webpack External Import
> **import() other chunks and modules from third parties, or other webpack builds themselves! At runtime!**
<p align="center">
[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
<a href="https://www.npmjs.com/package/webpack-external-import">
<img src="https://img.shields.io/npm/v/webpack-external-import.svg" alt="Version" />
</a>
<a href="https://www.npmjs.com/package/webpack-external-import">
<img src="https://img.shields.io/npm/dt/webpack-external-import.svg" alt="Downloads" />
</a>
<a href="https://www.npmjs.com/package/webpack-external-import">
<img src="https://img.shields.io/npm/dm/webpack-external-import.svg" alt="License" />
</a>
<a href="https://www.npmjs.com/package/webpack-external-import">
<img src="https://img.shields.io/npm/l/webpack-external-import.svg" alt="License" />
</a>
</p>
<p align="center">
<img src="docs/webpack-external-import.png" width="40%" alt="webpack-external-import" />
</p>
> This project has been rewritten into the Webpack core. Its far more stable and available on npm webpack@5.0.0-beta.16 https://github.com/webpack/webpack/issues/10352
> ### ⚠️ This project no longer under development as been enhanced in the webpack 5 core ⚠️
> ### See the examples on module federation in webpack 5
\*\*To jump to the _development_ section [click here](#development--debugging)
# Installation
### npm
```sh
npm install webpack-external-import --save
```
### Yarn
```sh
yarn add webpack-external-import
```
### Version 2.0!
Major rewrite which has taken the original concept and built it directly into webpack runtime.
A big achievement in this release is **tree-shaking support**
If you want to read me about what this tool does.
Read the following:
- https://link.medium.com/L5zHiwylI3
- working on more use cases and writing about V2
## Getting Started
1. Add `webpack-external-import/webpack` to your webpack plugins:
```js
// techblog.webpack.config.js
const URLImportPlugin = require("webpack-external-import/webpack");
{
plugins: [
new URLImportPlugin({
manifestName: "website-one"
})
];
}
// otherblog.webpack.config
const URLImportPlugin = require("webpack-external-import/webpack");
{
plugins: [
new URLImportPlugin({
manifestName: "website-two"
})
];
}
```
2. If you are interleaving webpack bundles, load their manifests somewhere
```js
// index.js
import { corsImport } from "webpack-external-import";
import React from "react";
import ReactDOM from "react-dom";
import App from "./App.jsx";
// using Date.now() for cache busting the file. It should only less than 2kb
corsImport(`http://localhost:3002/importManifest.js?${Date.now()}`).then(() => {
ReactDOM.render(<App />, document.getElementById("app"));
});
// you could also use native imports
import(
/* webpackIgnore:true */ `http://localhost:3002/importManifest.js?${Date.now()}`
).then(() => {
ReactDOM.render(<App />, document.getElementById("app"));
});
```
## Usage
This plugin works with any Webpack driven application
#### Vanilla JS
This assumes a import manifest was loaded somewhere else in the application already.
If you have not imported manifest then wrap your function in another promise:
```js
corsImport("http://localhost:3002/importManifest.js").then(() => {
someFunction();
});
```
As long as the `importManifest` was loaded - this is how it would be used
`__webpack_require_.interleaved()` expects a module to contain both the module.id and the namespace
This allows external-import to know where to interleave from.
`__webpack_require_.interleaved([namespace]/[module.id])`
Below is an example of interleaving a module from `website-2`
```js
// import a chunk from another website build with webpack-external-import
__webpack_require__
.interleaved("website-2/ValidationRules")
.then(validationRules => {
// proceed to use as a you would with a normal require statement
validationRules.validateObject(someObject);
});
```
### With JSX
`ExternalComponent` exists for ease of use with React Components and is as SFC using React.Hooks
```js
import { ExternalComponent } from "webpack-external-import";
class SomeComponent extends Component {
render() {
return (
<div>
<ExternalComponent
interleave={__webpack_require__.interleaved(
"website-2/TitleComponent"
)}
export="Title"
title="Some Heading"
/>
</div>
);
}
}
```
## What is the use of `webpack-external-import` ?
- **Load components over the wire** - Pull in components at runtime.
- **Build leaner micro-frontends (MFE)** -
Micro-frontends can share bundle chunks and resources with each other while remaining self-contained, removing needless code duplication.
- **Split a large, multi-team app into separate deployable chunks while keeping it as one SPA** - Large apps can be split into separate feature bundles that can be deployed independently, reducing deployment bottlenecks.
- **Manage common js/vendor files automatically.** - Instead of dealing with peer dependencies, externals, or anything else, you can load the dependency from a remote source.
- **LOSA Style frontend architecture** - Run multiple apps on a single page.
- **FOSA Style frontend orchestration** - Powerful frontend orchestration, self-organizing application architecture. Many builds act as one
### Advanced Setup - Injecting Webpack modules from another build
Use the webpack plugin to inject webpack modules from another build into your build.
_**Important**: Make sure manifestName_ is unique per webpack build.
If you have multiple builds, they all need to have a unique manifestName
**webpack.config.js**
```js
const URLImportPlugin = require("webpack-external-import/webpack");
{
plugins: [
new URLImportPlugin({
manifestName: "website-one"
})
];
}
```
## Mark Files for interleaving
Pretend we have two separate apps that each have their _independent_ build. We want to share a module from one of our apps with the other.
To do this, you must add an `interleave` object to `package.json`.
The `interleave` object tells the plugin to make the module accessible through a predictable name.
For example:
```json
// website-two package.json
{
"name": "some-package-name",
"interleave": {
"src/components/Title/index.js": "TitleComponent",
"src/components/hello-world/index.js": "SomeExternalModule"
}
}
```
```js
// website-one App.js
__webpack_require__
.interleaved("website-3/TitleComponentWithCSSFile")
.then(TitleComponentWithCSSFile => <TitleComponentWithCSSFile />);
```
This ensures a easy way for other consumers, teams, engineers to look up what another project or team is willing
to allow for interleaving
## Working with Webpack Externals
It's important to follow the instructions below if you are planning to use Webpack externals.
This plugin must be installed on all builds - it is intended that the build creating providing external is built by this plugin.
Externals work best in scenarios where the "host" app should supplying dependencies to an interleaved one.
**Providing Externals**
To support webpack externals, you will need to use `provideExternals` to specify externals
**Note:** you must use `provideExternals` **instead** of the webpack `externals` option.
```js
new URLImportPlugin({
provideExternals: {
react: "React"
}
});
```
**Consuming Externals**
To consume externals, you will need to use `useExternals` to inform webpack that the interleaved app should use the module specified by `provideExternals`
```js
new URLImportPlugin({
useExternals: {
react: "React"
}
});
```
## Full Example
**WEBSITE-ONE**
```js
// app.js
import React, { Component } from "react";
import { ExternalComponent } from "webpack-external-import";
import HelloWorld from "./components/goodbye-world";
import "react-select";
class App extends Component {
constructor(props) {
super(props);
this.state = {
titleUrl: null,
manifestLoaded: false,
loaded: false
};
}
componentDidMount() {
__webpack_require__
.interleaved("website-3/TitleComponentWithCSSFile")
.then(TitleComponentWithCSSFile =>
console.log(TitleComponentWithCSSFile)
);
}
renderDynamic = () => {
const { loaded } = this.state;
if (!loaded) return null;
return __webpack_require__("SomeExternalModule").default();
};
render() {
return (
<div>
<HelloWorld />
<ExternalComponent
interleave={__webpack_require__.interleaved(
"website-2/TitleComponent"
)}
export="Title"
module="TitleComponent"
title="Some Heading"
/>
<ExternalComponent
interleave={__webpack_require__.interleaved(
"website-3/TitleComponentWithCSSFile"
)}
export="Title"
title="Title Component With CSS File Import"
/>
{this.renderDynamic()}
</div>
);
}
}
Promise.all([
corsImport(`http://localhost:3002/importManifest.js?${Date.now()}`),
corsImport(`http://localhost:3003/importManifest.js?${Date.now()}`)
]).then(() => {
ReactDOM.render(<App />, document.getElementById("app"));
});
```
**WEBSITE-TWO**
```json
// package.json
{
"name": "website-two",
"version": "0.0.0-development",
"author": "Zack Jackson <zack@ScriptedAlchemy.com> (https://github.com/ScriptedAlchemy)",
"interleave": {
"src/components/Title/index.js": "TitleComponentWithCSSFile",
"src/components/Title/style.css": "TitleComponentWithCSSFileCSS",
"src/components/hello-world/index.js": "SomeExternalModule"
}
}
```
## API:
```js
module.exports = {
plugins: [
new URLImportPlugin({
manifestName: "website-one",
fileName: "importManifest.js",
basePath: ``,
publicPath: `//localhost:3001/`,
writeToFileEmit: false,
seed: null,
filter: null,
debug: true,
useExternals: {},
provideExternals: {}
})
]
};
```
### `options.fileName`
Type: `String`<br>
Default: `importManifest.js`
The manifest filename in your output directory.
### `options.publicPath`
Type: `String`
Default: `output.publicPath`
A path prefix that will be added to values of the manifest.
### `options.basePath`
Type: `String`
A path prefix for all keys. Useful for including your output path in the manifest.
### `options.writeToFileEmit`
Type: `Boolean`<br>
Default: `false`
If set to `true` will emit to build folder and memory in combination with `webpack-dev-server`
### `options.seed`
Type: `Object`<br>
Default: `{}`
A cache of key/value pairs to used to seed the manifest. This may include a set of [custom key/value](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/manifest.json) pairs to include in your manifest or may be used to combine manifests across compilations in [multi-compiler mode](https://github.com/webpack/webpack/tree/master/examples/multi-compiler). To combine manifests, pass a shared seed object to each compiler's ManifestPlugin instance.
### `options.filter`
Type: `Function(FileDescriptor): Boolean`
### `options.testPath`
Type: `Function(Object, FileDescriptor): Object`<br>
Default: `src`
Test resource path to see if plugin should apply transformations
### `options.useExternals`
Type: `Object`<br>
Default: `{}`
Informs the webpack treat the following dependencies as externals.
Works the same way externals does.
### `options.provideExternals`
Type: `Object`<br>
Default: `{}`
Informs webpack to provide the dependencies listed in the object to other apps using `useExternals`
### **ExternalComponent**
React Component
#### **Props**:
**`src`: string** - a url to a javascript file, note it will need to be built by another webpack build running this plugin
**`interleave`: function** - the `__webpack_require__.interleave()` function, which will return a module
**`export`: string** - The named export to use as a component from the module being imported
### The entry manifest
Each webpack build using the webpack plugin emits a manifest file to the build output directory.
The manifest allows you to find a chunk that you want, even if the name has been hashed.
Below is an example of using the manifest.
In this file, I am importing code from another website/build. My application is loading website two's manifest, which is automatically added to `window.entryManifest` under the `manifestName` I set in the webpack plugin. After that, I'm importing a chunk from website-two, in this case - the chunk is code-split.
```js
componentDidMount() {
corsImport('http://localhost:3002/importManifest.js').then(() => {
const Title = __webpack_require__
.interleaved("website-two/TitleComponent")
Title.then(console.log) // => Module {default: ()=>{}, Title: ()=>{}}
});
}
```
## DEMO
How to start using the demo
In the _root directory_, run the following
1. run `yarn install`
2. run `yarn demo` from the root directory
3. browse to [localhost:3001](http://localhost:3001) and you will see components from two other websites
This command will install, all dependencies, build the source for the plugin, install the demo dependencies, run all builds and start serving
## Development & Debugging
How to start the demo in debug mode, using node --inspect and connecting to a chrome debugger
> This is mainly for debugging the webpack plugin
In the root directory, run the following
1. `yarn install`
2. `yarn demo:debug` from the root directory
3. browse to [localhost:3001](http://localhost:3001)
**Note:** _[localhost:3001](http://localhost:3001) is the "consumer app, while the other is the provider app". Both apps work independently and you should check both of them out (they are extremely basic)_
Open chrome dev tools and you should see the box highlighted below appear, click on it to connect to the webpack debugger
![GitHub Logo](/docs/inspect.png)
### Logging
The default compilation removes console log statements via `babel-plugin-transform-remove-console`, which is run when `BABEL_ENV=production` (default). To compile a version with logging enabled, run `yarn compile` directly.
+35
View File
@@ -0,0 +1,35 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _loadjs = _interopRequireDefault(require("loadjs"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var corsImport = function corsImport(url) {
if (!url) {
return new Promise(function (resolve, reject) {
return reject(new Error("no url in corsImport"));
});
}
if (_loadjs["default"].isDefined(url)) {
return new Promise(function (resolve) {
resolve();
});
}
(0, _loadjs["default"])(url, url);
return new Promise(function (resolve, reject) {
_loadjs["default"].ready(url, {
success: resolve,
error: reject
});
});
};
var _default = corsImport;
exports["default"] = _default;
+23
View File
@@ -0,0 +1,23 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
Object.defineProperty(exports, "corsImport", {
enumerable: true,
get: function get() {
return _corsImport["default"];
}
});
Object.defineProperty(exports, "ExternalComponent", {
enumerable: true,
get: function get() {
return _react["default"];
}
});
var _corsImport = _interopRequireDefault(require("./corsImport"));
var _react = _interopRequireDefault(require("./react"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
+177
View File
@@ -0,0 +1,177 @@
{
"_args": [
[
"webpack-external-import@2.2.4",
"/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series"
]
],
"_from": "webpack-external-import@2.2.4",
"_id": "webpack-external-import@2.2.4",
"_inBundle": false,
"_integrity": "sha512-yJUHeu/UaZ8o0gCQyor6nsjEVdgc3ao8w7E6j28Dh1BanMxnqm0PumdElh2C5z/DMTcw1knQbpEArRo6/knNog==",
"_location": "/webpack-external-import",
"_phantomChildren": {},
"_requested": {
"type": "version",
"registry": true,
"raw": "webpack-external-import@2.2.4",
"name": "webpack-external-import",
"escapedName": "webpack-external-import",
"rawSpec": "2.2.4",
"saveSpec": null,
"fetchSpec": "2.2.4"
},
"_requiredBy": [
"/extract-css-chunks-webpack-plugin"
],
"_resolved": "https://registry.npmjs.org/webpack-external-import/-/webpack-external-import-2.2.4.tgz",
"_spec": "2.2.4",
"_where": "/mnt/Foxconn/Digitalent/Deverloper/liff-push_2series",
"author": {
"name": "Zack Jackson",
"email": "zack@ScriptedAlchemy.com",
"url": "https://github.com/ScriptedAlchemy"
},
"babel": {
"presets": [
"@babel/preset-env",
"@babel/preset-react"
],
"plugins": [
"@babel/plugin-proposal-optional-chaining"
],
"env": {
"production": {
"plugins": [
"transform-remove-console"
]
}
}
},
"bugs": {
"url": "https://github.com/ScriptedAlchemy/webpack-external-import/issues"
},
"config": {
"commitizen": {
"path": "./node_modules/cz-conventional-changelog"
}
},
"dependencies": {
"assert": "^2.0.0",
"dimport": "^1.0.0",
"fs-extra": "^8.1.0",
"loadjs": "^4.2.0",
"mem": "^6.0.1",
"pkg-up": "^3.1.0",
"tapable": "^1.1.3"
},
"description": "dynamic import() external urls!",
"devDependencies": {
"@babel/cli": "7.8.4",
"@babel/core": "7.8.4",
"@babel/helper-module-imports": "7.8.3",
"@babel/plugin-proposal-class-properties": "7.8.3",
"@babel/plugin-proposal-optional-chaining": "7.8.3",
"@babel/plugin-syntax-dynamic-import": "7.8.3",
"@babel/plugin-transform-react-jsx": "7.8.3",
"@babel/plugin-transform-runtime": "7.8.3",
"@babel/preset-env": "7.8.4",
"@babel/preset-react": "7.8.3",
"@babel/traverse": "7.8.4",
"babel-core": "7.0.0-bridge.0",
"babel-eslint": "10.0.3",
"babel-loader": "8.0.6",
"babel-plugin-transform-remove-console": "6.9.4",
"babel-watch": "7.0.0",
"commitizen": "4.0.3",
"concurrently": "5.1.0",
"cross-env": "7.0.0",
"cz-conventional-changelog": "3.1.0",
"eslint": "6.8.0",
"eslint-config-airbnb": "18.0.1",
"eslint-config-prettier": "6.10.0",
"eslint-plugin-import": "2.20.1",
"eslint-plugin-jsx-a11y": "6.2.3",
"eslint-plugin-prettier": "3.1.2",
"eslint-plugin-react": "7.18.3",
"eslint-plugin-react-hooks": "1.7.0",
"flow-bin": "0.119.1",
"html-webpack-plugin": "3.2.0",
"jest": "25.1.0",
"jest-haste-map": "25.1.0",
"jest-puppeteer": "4.4.0",
"jest-resolve": "25.1.0",
"marked": "0.7.0",
"node-cipher": "6.3.3",
"paralleljs": "0.2.1",
"prettier": "1.19.1",
"prop-types": "15.7.2",
"puppeteer": "2.1.1",
"react": "16.8.6",
"react-dom": "16.8.6",
"regenerator-runtime": "0.13.3",
"schema-utils": "2.6.4",
"semantic-release": "17.0.4",
"source-map": "0.7.3",
"travis-github-status": "1.6.3",
"webpack": "4.41.6",
"webpack-cli": "3.3.11",
"webpack-dev-server": "3.10.3"
},
"files": [
"webpack",
"babel",
"corsImport.js",
"index.js",
"polyfill.js",
"react.js",
"loader"
],
"homepage": "https://github.com/ScriptedAlchemy/webpack-external-import#readme",
"keywords": [
"import url",
"dynamic imports url",
"over the wire",
"import() url",
"external url import",
"script injection",
"webpack import url",
"webpack",
"manifest",
"dynamic dll plugin",
"dll plugin",
"runtime"
],
"license": "MIT",
"name": "webpack-external-import",
"peerDependencies": {
"webpack": "^4.40.2"
},
"repository": {
"type": "git",
"url": "git+https://github.com/ScriptedAlchemy/webpack-external-import.git"
},
"scripts": {
"commit": "npx git-cz",
"compile": "rm -rf webpack index.js corsImport.js react.js polyfill.js; babel src -d .",
"demo": "cd manual; yarn && cd ../; concurrently \"yarn compile\" \"yarn demo:one\" \"yarn demo:two\" \"yarn demo:three\"",
"demo:debug": "cd manual; yarn && cd ../; concurrently \"yarn kill-ports\" \"yarn compile\" \"yarn demo:one\" \"yarn demo:two:debug\" \"yarn demo:three\"",
"demo:fast": "yarn compile && yarn demo:one:fast | yarn demo:two:fast",
"demo:one": "cd manual/website1; yarn manual:dev",
"demo:one:debug": "cd manual/website1; yarn && yarn manual:debug",
"demo:one:prod": "cd manual/website1; yarn && yarn manual:prod",
"demo:prod": "cd manual; yarn && cd ../; concurrently \"yarn kill-ports\" \"yarn compile\" \"yarn demo:one:prod\" \"yarn demo:two:prod\" \"yarn demo:three:prod \"",
"demo:three": "cd manual/website3; yarn manual:dev",
"demo:three:debug": "cd manual/website3; yarn && yarn manual:debug",
"demo:three:prod": "cd manual/website3; yarn && yarn manual:prod",
"demo:two": "cd manual/website2; yarn manual:dev",
"demo:two:debug": "cd manual/website2; yarn && yarn manual:debug",
"demo:two:prod": "cd manual/website2; yarn && yarn manual:prod",
"kill-ports": "lsof -ti:3001 | xargs kill -9; lsof -ti:3002 | xargs kill -9; lsof -ti:3003 | xargs kill -9",
"lint": "eslint --ext .js,.ts,.tsx src --fix",
"prepare": "BABEL_ENV=production yarn compile",
"semantic-release": "semantic-release",
"test": "yarn lint"
},
"version": "2.2.4"
}
+6
View File
@@ -0,0 +1,6 @@
"use strict";
// eslint-disable-next-line no-empty
if (typeof process !== "undefined") {} else if (!window["import"]) {
window["import"] = require("dimport/legacy");
}
+81
View File
@@ -0,0 +1,81 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _react = _interopRequireWildcard(require("react"));
var _propTypes = _interopRequireDefault(require("prop-types"));
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
function _getRequireWildcardCache() { if (typeof WeakMap !== "function") return null; var cache = new WeakMap(); _getRequireWildcardCache = function _getRequireWildcardCache() { return cache; }; return cache; }
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; }
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
var v2Effect = function v2Effect(props, setComponent) {
var interleave = props.interleave,
exportName = props["export"];
interleave.then(function (module) {
var Component = module["default"] ? module["default"] : module[exportName];
setComponent({
Component: Component
});
})["catch"](function (e) {
throw new Error("interleaving: ".concat(e));
});
};
var ExternalComponent = function ExternalComponent(props) {
var interleave = props.interleave,
exportName = props["export"],
cors = props.cors,
rest = _objectWithoutProperties(props, ["interleave", "export", "cors"]);
var _useState = (0, _react.useState)({
Component: null
}),
_useState2 = _slicedToArray(_useState, 2),
Component = _useState2[0].Component,
setComponent = _useState2[1];
(0, _react.useEffect)(function () {
v2Effect(props, setComponent);
}, []);
if (!Component) {
return null;
} // eslint-disable-next-line react/jsx-props-no-spreading
return _react["default"].createElement(Component, rest);
};
ExternalComponent.propTypes = {
// eslint-disable-next-line react/forbid-prop-types
interleave: _propTypes["default"].object.isRequired,
cors: _propTypes["default"].bool,
"export": _propTypes["default"].string
};
ExternalComponent.defaultProps = {
cors: false,
"export": null
};
var _default = ExternalComponent;
exports["default"] = _default;
+131
View File
@@ -0,0 +1,131 @@
"use strict";
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
var ExternalModule = require("webpack/lib/ExternalModule");
var ExternalModuleFactoryPlugin =
/*#__PURE__*/
function () {
function ExternalModuleFactoryPlugin(type, externals) {
_classCallCheck(this, ExternalModuleFactoryPlugin);
this.type = type;
this.externals = externals;
}
_createClass(ExternalModuleFactoryPlugin, [{
key: "apply",
value: function apply(normalModuleFactory) {
var _this = this;
var globalType = this.type;
normalModuleFactory.hooks.factory.tap("ExternalModuleFactoryPlugin", function (factory) {
return function (data, callback) {
var context = data.context;
var dependency = data.dependencies[0];
var handleExternal = function handleExternal(value, type, callback) {
if (typeof type === "function") {
callback = type;
type = undefined;
}
if (value === false) return factory(data, callback);
if (value === true) value = dependency.request;
if (type === undefined && /^[a-z0-9]+ /.test(value)) {
var idx = value.indexOf(" ");
type = value.substr(0, idx);
value = value.substr(idx + 1);
}
var externalModule = new ExternalModule(value, type || globalType, dependency.request);
externalModule.id = dependency.userRequest;
callback(null, externalModule);
return true;
};
var handleExternals = function handleExternals(externals, callback) {
if (typeof externals === "string") {
if (externals === dependency.request) {
return handleExternal(dependency.request, callback);
}
} else if (Array.isArray(externals)) {
var i = 0;
var next = function next() {
var asyncFlag;
var handleExternalsAndCallback = function handleExternalsAndCallback(err, module) {
if (err) return callback(err);
if (!module) {
if (asyncFlag) {
asyncFlag = false;
return;
}
return next();
}
callback(null, module);
};
do {
asyncFlag = true;
if (i >= externals.length) return callback();
handleExternals(externals[i++], handleExternalsAndCallback);
} while (!asyncFlag);
asyncFlag = false;
};
next();
return;
} else if (externals instanceof RegExp) {
if (externals.test(dependency.request)) {
return handleExternal(dependency.request, callback);
}
} else if (typeof externals === "function") {
externals.call(null, context, dependency.request, function (err, value, type) {
if (err) return callback(err);
if (value !== undefined) {
handleExternal(value, type, callback);
} else {
callback();
}
});
return;
} else if (_typeof(externals) === "object" && Object.prototype.hasOwnProperty.call(externals, dependency.request)) {
return handleExternal(externals[dependency.request], callback);
}
callback();
};
handleExternals(_this.externals, function (err, module) {
if (err) return callback(err);
if (!module) return handleExternal(false, callback);
return callback(null, module);
});
};
});
}
}]);
return ExternalModuleFactoryPlugin;
}();
module.exports = ExternalModuleFactoryPlugin;
+16
View File
@@ -0,0 +1,16 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addWebpackRegister = addWebpackRegister;
var Template = require("webpack/lib/Template"); // eslint-disable-next-line import/prefer-default-export
function addWebpackRegister(source) {
if (source) {
var splitSource = source.split("jsonpArray.push = webpackJsonpCallback;");
return Template.asString([splitSource[0].replace("var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);", Template.asString(['var webpackRegister = window["webpackRegister"] = window["webpackRegister"] || [];', "var oldJsonpFunction = jsonpArray.push.bind(jsonpArray);"])), "jsonpArray.push = function(data) {", Template.indent("webpackJsonpCallback(data)"), Template.indent(["data[0].forEach(function(chunkId) {", Template.indent(["if (interleaveDeferred[chunkId]) {", Template.indent("interleaveDeferred[chunkId].resolver[0](interleaveDeferred);"), "}"]), "});"]), "};", "webpackRegister.push = registerLocals;", splitSource[1]]);
}
}
+104
View File
@@ -0,0 +1,104 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.interleaveConfig = interleaveConfig;
exports.interleaveStyleConfig = interleaveStyleConfig;
exports.interleaveStyleJsConfig = interleaveStyleJsConfig;
exports.hasExternalizedModuleViaJson = void 0;
var _mem = _interopRequireDefault(require("mem"));
var _utils = require("./utils");
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }
var interleaveMap = (0, _utils.getInterleaveConfig)();
var hasExternalizedModuleViaJson = (0, _mem["default"])(function (moduleResource) {
if (!moduleResource || !interleaveMap) return;
var interleaveKeys = Object.keys(interleaveMap || {});
if (interleaveKeys) {
var foundMatch = interleaveKeys.find(function (item) {
return moduleResource.includes(item);
});
return interleaveMap[foundMatch] || false;
}
});
exports.hasExternalizedModuleViaJson = hasExternalizedModuleViaJson;
function interleaveConfig(_ref) {
var testPath = _ref.testPath,
manifestName = _ref.manifestName;
return {
test: function test(module) {
// check if module has a resource path (not virtual modules)
if (module.resource) {
return module.resource.includes(testPath) && !!hasExternalizedModuleViaJson(module.resource, manifestName);
}
},
name: function name(module) {
// Check if module is listed in the interleave interface
var foundValue = hasExternalizedModuleViaJson(module.resource, manifestName);
if (foundValue) return foundValue;
},
// force module into a chunk regardless of how its used
enforce: true // might need for next.js
// reuseExistingChunk: false,
};
}
function interleaveStyleConfig(_ref2) {
var manifestName = _ref2.manifestName;
return {
test: function test(module) {
// check if module has a resource path (not virtual modules)
if (module.constructor.name === "CssModule") {
return !!hasExternalizedModuleViaJson(module.identifier(), manifestName);
}
},
// eslint-disable-next-line no-unused-vars
name: function name(module, chunks, cacheGroupKey) {
// Check if module is listed in the interleave interface
if (!module.resource) {
var foundValue = hasExternalizedModuleViaJson(module.resource || module.identifier(), manifestName);
if (foundValue) return "".concat(foundValue, "-style");
}
return "styles";
},
// force module into a chunk regardless of how its used
chunks: "all",
enforce: true,
reuseExistingChunk: false
};
}
function interleaveStyleJsConfig(_ref3) {
var manifestName = _ref3.manifestName;
return {
test: function test(module) {
if (module.request && module.request.match(/\\(style-loader|css-loader|sass-loader)$/)) {
return true;
}
if (module.constructor.name === "CssModule") {
return false;
}
if (module.resource && module.resource.match(/\.(scss|css)$/)) {
return true;
}
return false;
},
name: function name(module, chunks) {
return "".concat(manifestName, "-stylejs");
},
chunks: "all",
enforce: true,
reuseExistingChunk: false
};
}
+525
View File
@@ -0,0 +1,525 @@
"use strict";
function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); }
function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); }
function _iterableToArrayLimit(arr, i) { if (!(Symbol.iterator in Object(arr) || Object.prototype.toString.call(arr) === "[object Arguments]")) { return; } var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; }
function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a 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); } }
function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; }
var path = require("path");
var fse = require("fs-extra");
var createHash = require("webpack/lib/util/createHash");
var fs = require("fs");
var ExternalModuleFactoryPlugin = require("./ExternalModuleFactory"); // const FunctionModuleTemplatePlugin = require("webpack/lib/FunctionModuleTemplatePlugin");
var _require = require("./utils"),
mergeDeep = _require.mergeDeep;
var _require2 = require("./requireExtentions"),
addInterleaveExtension = _require2.addInterleaveExtension,
addInterleaveRequire = _require2.addInterleaveRequire;
var _require3 = require("./beforeStartup"),
addWebpackRegister = _require3.addWebpackRegister;
var _require4 = require("./chunkSplitting"),
interleaveStyleConfig = _require4.interleaveStyleConfig,
interleaveStyleJsConfig = _require4.interleaveStyleJsConfig,
interleaveConfig = _require4.interleaveConfig,
hasExternalizedModuleViaJson = _require4.hasExternalizedModuleViaJson;
var _require5 = require("./localVars"),
addLocalVars = _require5.addLocalVars;
var _require6 = require("./optimizeChunk"),
wrapChunks = _require6.wrapChunks;
var emitCountMap = new Map();
function getFileType(str) {
var split = str.replace(/\?.*/, "").split(".");
return split.pop();
}
var URLImportPlugin =
/*#__PURE__*/
function () {
function URLImportPlugin(opts) {
_classCallCheck(this, URLImportPlugin);
var debug = (typeof v8debug === "undefined" ? "undefined" : _typeof(v8debug)) === "object" || /--debug|--inspect/.test(process.execArgv.join(" "));
if (!opts.manifestName) {
throw new Error("URLImportPlugin: You MUST specify a manifestName in your options. Something unique. Like {manifestName: my-special-build}");
}
this.opts = _objectSpread({
publicPath: null,
debug: debug || false,
testPath: "src",
basePath: "",
manifestName: "unknown-project",
fileName: "importManifest.js",
writeToFileEmit: false,
seed: null,
filter: null,
hashDigest: "base64",
hashDigestLength: 5,
context: null,
hashFunction: "md4"
}, opts || {});
}
_createClass(URLImportPlugin, [{
key: "apply",
value: function apply(compiler) {
var _options$optimization,
_options$optimization2,
_this = this,
_options$optimization3;
if (this.opts.debug) {}
var options = compiler === null || compiler === void 0 ? void 0 : compiler.options;
if (options.externals) {
throw new Error("URLImportPlugin: Externals must be applied via the plugin, not via webpack config object. Please see useExternals on the plugin documentation");
} // add to the existing webpack config
// adding a new splitChunks cache group called interleave
var chunkSplitting = (options === null || options === void 0 ? void 0 : (_options$optimization = options.optimization) === null || _options$optimization === void 0 ? void 0 : (_options$optimization2 = _options$optimization.splitChunks) === null || _options$optimization2 === void 0 ? void 0 : _options$optimization2.cacheGroups) || {};
chunkSplitting.stylejs = interleaveStyleJsConfig(this.opts);
chunkSplitting.style = interleaveStyleConfig(this.opts); // interleaveConfig figures out if a file meets the paramaters for interleaving
chunkSplitting.interleave = interleaveConfig(this.opts);
if (options.mode === "production") {
chunkSplitting.vendors = {
name: "".concat(this.opts.manifestName, "-vendors"),
test: /node_modules/,
priority: -10,
enforce: true,
maxSize: 50000
};
Object.assign(chunkSplitting["default"], {
maxSize: 50000
});
}
Object.assign(options.optimization || {}, {
namedChunks: true,
// dont rename exports when hoisting and tree shaking
providedExports: false
}); // likely will be refactored or removed, used for entryManifest.js to map chunks (this is V1 where its outside the runtime still)
if (this.opts.debug) {} // merge my added splitChunks config into the webpack config object passed in
Object.assign(options.optimization.splitChunks, {
chunks: "all"
});
mergeDeep(options, {
optimization: {
splitChunks: {
chunks: "all",
cacheGroups: chunkSplitting
}
}
});
Object.keys(chunkSplitting).forEach(function (key) {
var _chunkSplitting$key;
if (key === "interleave") {
return;
}
chunkSplitting[key].automaticNamePrefix = "".concat(_this.opts.manifestName, "~").concat((chunkSplitting === null || chunkSplitting === void 0 ? void 0 : (_chunkSplitting$key = chunkSplitting[key]) === null || _chunkSplitting$key === void 0 ? void 0 : _chunkSplitting$key.automaticNamePrefix) || "");
});
Object.assign(options.optimization, {
// node debugger breaks with TerserPlugin
minimizer: this.opts.debug ? [] : options.optimization.minimizer,
splitChunks: ((_options$optimization3 = options.optimization) === null || _options$optimization3 === void 0 ? void 0 : _options$optimization3.splitChunks) || {}
}); // forcefully mutate it
Object.assign(options.optimization.splitChunks, {
chunks: "all",
cacheGroups: chunkSplitting
});
if (this.opts.debug) {} // eslint-disable-next-line no-unused-vars
compiler.hooks.thisCompilation.tap("URLImportPlugin", function (compilation) {// TODO: throw warning when changing module ID type
// if (options.ignoreOrder) {
// compilation.warnings.push(
// new Error(
// `chunk ${chunk.name || chunk.id} [${pluginName}]\n`
// + 'Conflicting order between:\n'
// + ` * ${fallbackModule.readableIdentifier(
// requestShortener,
// )}\n`
// + `${bestMatchDeps
// .map(m => ` * ${m.readableIdentifier(requestShortener)}`)
// .join('\n')}`,
// ),
// );
// }
});
var moduleAssets = {};
var outputFolder = compiler.options.output.path;
var outputFile = path.resolve(outputFolder, this.opts.fileName);
var outputName = path.relative(outputFolder, outputFile);
var moduleAsset = function moduleAsset(_ref, file) {
var userRequest = _ref.userRequest;
if (userRequest) {
moduleAssets[file] = path.join(path.dirname(file), path.basename(userRequest));
}
};
var emit = function emit(compilation, compileCallback) {
var emitCount = emitCountMap.get(outputFile) - 1;
emitCountMap.set(outputFile, emitCount);
var seed = _this.opts.seed || {};
var publicPath = _this.opts.publicPath != null ? _this.opts.publicPath : compilation.options.output.publicPath;
var stats = compilation.getStats().toJson();
if (_this.opts.debug) {}
var files = compilation.chunks.reduce(function (f, chunk) {
return chunk.files.reduce(function (fx, filePath) {
var name = chunk.id ? chunk.id : null;
if (name) {
name = "".concat(name, ".").concat(getFileType(filePath));
} else {
// For nameless chunks, just map the files directly.
name = filePath;
}
return fx.concat({
path: filePath,
chunk: chunk,
name: name,
isChunk: true,
isAsset: false,
isModuleAsset: false
});
}, f);
}, []); // module assets don't show up in assetsByChunkName.
// we're getting them this way;
files = stats.assets.reduce(function (fx, asset) {
var name = moduleAssets[asset.name];
if (name) {
return fx.concat({
path: asset.name,
name: name
});
}
var isEntryAsset = asset.chunks.length > 0;
if (isEntryAsset) {
return fx;
}
return fx.concat({
path: asset.name,
name: asset.name
});
}, files);
files = files.filter(function (file) {
// Don't add hot updates to manifest
var isUpdateChunk = file.path.includes("hot-update"); // Don't add manifest from another instance
var isManifest = emitCountMap.get(path.join(outputFolder, file.name)) !== undefined;
return !isUpdateChunk && !isManifest;
});
if (_this.opts.debug) {} // Append optional basepath onto all references.
// This allows output path to be reflected in the manifest.
if (_this.opts.basePath) {
files = files.map(function (file) {
return _objectSpread({}, file, {
name: _this.opts.basePath + file.name
});
});
}
if (publicPath) {
// Similar to basePath but only affects the value (similar to how
// output.publicPath turns require('foo/bar') into '/public/foo/bar', see
// https://github.com/webpack/docs/wiki/configuration#outputpublicpath
files = files.map(function (file) {
return _objectSpread({}, file, {
path: publicPath + file.path
});
});
}
files = files.map(function (file) {
return _objectSpread({}, file, {
name: file.name.replace(/\\/g, "/"),
path: file.path.replace(/\\/g, "/")
});
});
if (_this.opts.filter) {
files = files.filter(_this.opts.filter);
}
if (_this.opts.debug) {}
var manifest = files.reduce(function (m, file) {
return _objectSpread({}, m, _defineProperty({}, file.name, {
path: file.path
}));
}, seed);
if (_this.opts.debug) {}
var isLastEmit = emitCount === 0;
if (isLastEmit) {
var cleanedManifest = Object.entries(manifest).reduce(function (acc, _ref2) {
var _asset$path;
var _ref3 = _slicedToArray(_ref2, 2),
key = _ref3[0],
asset = _ref3[1];
if (!(asset === null || asset === void 0 ? void 0 : (_asset$path = asset.path) === null || _asset$path === void 0 ? void 0 : _asset$path.includes(".map"))) {
return Object.assign(acc, _defineProperty({}, key, asset));
}
return acc;
}, {});
var serialize = function serialize(manifest) {
return "if(!window.entryManifest) {window.entryManifest = {}}; window.entryManifest[\"".concat(_this.opts.manifestName, "\"] = ").concat(JSON.stringify(manifest));
};
var output = serialize(cleanedManifest);
if (_this.opts.debug) {} // eslint-disable-next-line no-param-reassign
compilation.assets[outputName] = {
source: function source() {
return output;
},
size: function size() {
return output.length;
}
};
if (_this.opts.writeToFileEmit) {
fse.outputFileSync(outputFile, output);
}
}
if (compiler.hooks) {
compiler.hooks.webpackURLImportPluginAfterEmit.call(manifest);
} else {
compilation.applyPluginsAsync("webpack-manifest-plugin-after-emit", manifest, compileCallback);
}
};
function beforeRun(comp, callback) {
var emitCount = emitCountMap.get(outputFile) || 0;
emitCountMap.set(outputFile, emitCount + 1);
if (callback) {
callback();
}
}
if (compiler.hooks) {
var _require7 = require("tapable"),
SyncWaterfallHook = _require7.SyncWaterfallHook;
var pluginOptions = {
name: "URLImportPlugin",
stage: Infinity
}; // eslint-disable-next-line no-param-reassign
compiler.hooks.webpackURLImportPluginAfterEmit = new SyncWaterfallHook(["manifest"]);
compiler.hooks.compile.tap("ExternalsPlugin", function (_ref4) {
var normalModuleFactory = _ref4.normalModuleFactory;
new ExternalModuleFactoryPlugin(options.output.libraryTarget, _this.opts.useExternals).apply(normalModuleFactory);
});
compiler.hooks.compilation.tap("URLImportPlugin", function (compilation) {
var mainTemplate = compilation.mainTemplate; // Add another webpack__require method to the webpack runtime
// this new method will allow a interleaved component to be required and automatically download its dependencies
// it returns a promise so the actual interleaved module is not executed until any missing dependencies are loaded
mainTemplate.hooks.requireExtensions.tap("URLImportPlugin", function (source) {
return [addInterleaveExtension, addInterleaveRequire].reduce(function (sourceCode, extension) {
return extension(sourceCode, mainTemplate.requireFn, _this.opts);
}, source);
}); // TODO add an option for this
if (_this.afterOptimizations) {
// before chunk files are optimized
compilation.hooks.beforeOptimizeChunkAssets.tap("URLImportPlugin", function (chunks) {
// access all chunks webpack created, then add some code to each chunk file, which is run when a chunk is
// loaded on a page as <script>
wrapChunks(compilation, chunks);
});
} else {
// adfter chunk files are optimized
compilation.hooks.optimizeChunkAssets.tapAsync("URLImportPlugin", function (chunks, done) {
wrapChunks(compilation, chunks);
done();
});
} // Expose chunk registration functions and bindings from webpack runtime to the window
// webpack does this and its how code splitting works. It exposes window.webpackJsonP
// This registration system works just like webpacks, it exposes a function that allows information to be passed
// into webpack runtime, because the function is in webpack runtime, i have access to all of webpacks internals
mainTemplate.hooks.beforeStartup.tap("URLImportPlugin", function (source) {
return addWebpackRegister(source, options.output.jsonpFunction);
}); // add variables to webpack runtime which are available throughout all functions and closures within the runtime
// localVars are like global variables for webpack, anything can access them.
mainTemplate.hooks.localVars.tap("URLImportPlugin", addLocalVars);
});
compiler.hooks.compilation.tap("URLImportPlugin", function (compilation) {
var usedIds = new Set(); // creates hashed module IDs based on the contents of the file - works like [contenthash] but for each module
compilation.hooks.beforeModuleIds.tap("URLImportPlugin", function (modules) {
var _this$opts;
var provideExternals = Object.keys(((_this$opts = _this.opts) === null || _this$opts === void 0 ? void 0 : _this$opts.provideExternals) || {}); // eslint-disable-next-line no-restricted-syntax
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = modules[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var _module = _step.value;
if (provideExternals.includes(_module.rawRequest)) {
_module.id = _module.rawRequest;
}
if (_module.id === null && _module.resource) {
var hash = createHash(_this.opts.hashFunction);
var resourcePath = _module.resource;
if (resourcePath.indexOf("?") > -1) {
var _resourcePath$split = resourcePath.split("?");
var _resourcePath$split2 = _slicedToArray(_resourcePath$split, 1);
resourcePath = _resourcePath$split2[0];
}
try {
var exports = "";
if (Array.isArray(_module.usedExports)) {
exports = _module.usedExports.join(".");
}
hash.update(fs.readFileSync(resourcePath) + exports);
} catch (ex) {
throw ex;
}
var hashId = hash.digest(_this.opts.hashDigest);
var len = _this.opts.hashDigestLength;
while (usedIds.has(hashId.substr(0, len))) {
len++;
}
_module.id = hashId.substr(0, len);
usedIds.add(_module.id);
} else if (_this.opts.debug) {// console.log("Module with no ID", module);
}
var externalModule = hasExternalizedModuleViaJson(_module.resource);
if (externalModule || false) {
var _module$buildMeta;
// add exports back to usedExports, prevents tree shaking on module
Object.assign(_module, {
usedExports: (_module === null || _module === void 0 ? void 0 : (_module$buildMeta = _module.buildMeta) === null || _module$buildMeta === void 0 ? void 0 : _module$buildMeta.providedExports) || true
});
if (externalModule) {
_module.id = externalModule;
}
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
});
compiler.hooks.compilation.tap(pluginOptions, function (_ref5) {
var hooks = _ref5.hooks;
// TODO: remove in ^2.2
hooks.moduleAsset.tap(pluginOptions, moduleAsset);
}); // writes the importManifest file containing a map of Chunk IDs to the cache busted JS files
compiler.hooks.emit.tap(pluginOptions, emit);
compiler.hooks.run.tap(pluginOptions, beforeRun);
compiler.hooks.watchRun.tap(pluginOptions, beforeRun);
} else {
compiler.plugin("compilation", function (compilation) {
compilation.plugin("module-asset", moduleAsset);
});
compiler.plugin("emit", emit);
compiler.plugin("before-run", beforeRun);
compiler.plugin("watch-run", beforeRun);
}
}
}]);
return URLImportPlugin;
}();
module.exports = URLImportPlugin;
+214
View File
@@ -0,0 +1,214 @@
"use strict";
module.exports.requireInterleaveExtension = function () {
/* global interleaveDeferredCopy, interleaveDeferred,installedChunks */
// interleaveDeferredCopy, interleaveDeferred, installedChunks are globals inside the webpack runtime scope
function interleaveCss(args) {
// Interleaved CSS loading
var installedChunks = args.installedChunks,
chunkId = args.chunkId,
foundChunk = args.foundChunk,
finalResolve = args.finalResolve; // 0 means 'already installed'
if (installedChunks[chunkId] !== 0) {
installedChunks[chunkId] = new Promise(function (resolve, reject) {
var fullhref = foundChunk.path;
var existingLinkTags = document.getElementsByTagName("link");
for (var i = 0; i < existingLinkTags.length; i++) {
var tag = existingLinkTags[i];
var linkDataHref = tag.getAttribute("data-href") || tag.getAttribute("href");
if (tag.rel === "stylesheet" && linkDataHref === fullhref) resolve();
return finalResolve[0]();
}
var existingStyleTags = document.getElementsByTagName("style");
for (var _i = 0; _i < existingStyleTags.length; _i++) {
var _tag = existingStyleTags[_i];
var styleDataHref = _tag.getAttribute("data-href");
if (styleDataHref === fullhref) interleaveDeferred[chunkId].resolver[0]();
interleaveDeferredCopy[chunkId] = interleaveDeferred[chunkId];
delete interleaveDeferred[chunkId];
finalResolve[0]();
return;
}
var linkTag = document.createElement("link");
linkTag.rel = "stylesheet";
linkTag.type = "text/css";
linkTag.onload = function () {
// trigger a promise resolution for anything else waiting
interleaveDeferred[chunkId].resolver[0](); // remove from object after resolving it
delete interleaveDeferred[chunkId]; // resolve the promise chain in this function scope
finalResolve[0]();
};
linkTag.onerror = function (event) {
var request = event && event.target && event.target.src || fullhref;
var err = new Error("Loading CSS chunk ".concat(chunkId, " failed.\n(").concat(request, ")"));
err.code = "CSS_CHUNK_LOAD_FAILED";
err.request = request;
linkTag.parentNode.removeChild(linkTag);
reject(err);
interleaveDeferred[chunkId].resolver[1](err);
delete interleaveDeferred[chunkId];
finalResolve[1](err);
};
linkTag.href = fullhref;
if (linkTag.href.indexOf("".concat(window.location.origin, "/")) !== 0) {
linkTag.crossOrigin = true;
}
var target = document.querySelector("body");
target.insertBefore(linkTag, target.firstChild);
}).then(function () {
installedChunks[chunkId] = 0;
});
}
} // registerLocals chunk loading for javascript
__webpack_require__.interleaved = function (moduleIdWithNamespace, isNested) {
var initialRequestMap = {};
var interleavePromises = [];
var finalResolve;
var finalPromise = new Promise(function (resolve, reject) {
finalResolve = [resolve, reject];
});
if (!isNested) {}
if (isNested) {}
var chunkId = moduleIdWithNamespace.substring(moduleIdWithNamespace.indexOf("/") + 1);
var namespace = moduleIdWithNamespace.split("/")[0];
var namespaceObj = window.entryManifest[namespace];
var foundChunk = namespaceObj[chunkId] || namespaceObj["".concat(chunkId, ".js")];
if (!foundChunk) {
finalResolve[1]("webpack-external-import: unable to find ".concat(chunkId));
return finalPromise;
}
var isCSS = chunkId.indexOf(".css") !== -1;
if (!isNested) {
initialRequestMap[moduleIdWithNamespace] = chunkId;
}
var installedChunkData = installedChunks[chunkId];
if (installedChunkData !== 0 && !isCSS) {
// 0 means 'already installed'.
// a Promise means "currently loading".
if (installedChunkData) {
interleavePromises.push(installedChunkData[2]);
} else {
if (!interleaveDeferred[chunkId]) {
// current main chunk
var resolver;
var _promise = new Promise(function (resolve, reject) {
resolver = [resolve, reject];
});
interleaveDeferred[chunkId] = {
promise: _promise,
resolver: resolver
};
} // setup Promise in chunk cache
var promise = new Promise(function (resolve, reject) {
installedChunkData = installedChunks[chunkId] = [resolve, reject];
});
interleavePromises.push(installedChunkData[2] = promise);
// start chunk loading
var script = document.createElement("script");
script.charset = "utf-8";
script.timeout = 120;
if (__webpack_require__.nc) {
script.setAttribute("nonce", __webpack_require__.nc);
}
script.src = foundChunk.path; // create error before stack unwound to get useful stacktrace later
var error = new Error();
var onScriptComplete = function onScriptComplete(event) {
// avoid mem leaks in IE.
script.onerror = script.onload = null; // eslint-disable-next-line no-use-before-define
clearTimeout(timeout);
var chunk = installedChunks[chunkId];
if (chunk !== 0) {
if (chunk) {
var errorType = event && (event.type === "load" ? "missing" : event.type);
var realSrc = event && event.target && event.target.src;
error.message = "Loading chunk ".concat(chunkId, " failed. (").concat(errorType, ": ").concat(realSrc, ")");
error.name = "ChunkLoadError";
error.type = errorType;
error.request = realSrc;
chunk[1](error);
delete interleaveDeferred[chunkId];
finalResolve[1](error);
}
installedChunks[chunkId] = undefined;
}
var interleaveDeferredKeys = Object.keys(interleaveDeferred);
interleaveDeferredCopy[chunkId] = interleaveDeferred[chunkId];
delete interleaveDeferred[chunkId];
var chunksToInstall = interleaveDeferredKeys.filter(function (item) {
return installedChunks[item] === undefined;
});
if (!chunksToInstall.length) {
finalResolve[0]();
} // recursively find more chunks to install and push them into the interleave function
// once all nested calls are done, resolve the current functions promise
Promise.all(chunksToInstall.map(function (chunk) {
return __webpack_require__.interleaved("".concat(namespace, "/").concat(chunk), true);
})).then(finalResolve[0]);
};
var timeout = setTimeout(function () {
onScriptComplete({
type: "timeout",
target: script
});
}, 120000);
script.onerror = script.onload = onScriptComplete;
document.head.appendChild(script);
}
}
if (installedChunks[chunkId] !== 0 && isCSS) {
interleaveCss({
installedChunks: installedChunks,
chunkId: chunkId,
foundChunk: foundChunk,
finalResolve: finalResolve
});
}
if (function () {}) {}
return finalPromise.then(function () {
if (!isNested) return __webpack_require__(chunkId);
});
};
};
+11
View File
@@ -0,0 +1,11 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addLocalVars = addLocalVars;
// eslint-disable-next-line import/prefer-default-export
function addLocalVars(source, chunk, compilationHash) {
return [source, "", "// object to store interleaved JavaScript chunks", "var interleaveMap = {};", "// object to store interleaved CSS chunks", "var interleavedCssChunks = {}", "var compilationHash = '".concat(compilationHash, "'")].join("\n");
}
+173
View File
@@ -0,0 +1,173 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.wrapChunks = wrapChunks;
function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; }
function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
var ModuleFilenameHelpers = require("webpack/lib/ModuleFilenameHelpers");
var _require = require("webpack-sources"),
ConcatSource = _require.ConcatSource;
var mem = require("mem");
function wrapFile(compilation, fileName, allModulesNeeded, chunkKeys) {
// create a stringified array
var outputOptions = compilation.output;
var pushArguments = JSON.stringify([// pass the source compilation hash to figure out if a chunk is being required by its own build - if so, dont register anything
{
hash: compilation.hash,
publicPath: (outputOptions === null || outputOptions === void 0 ? void 0 : outputOptions.publicPath) || "/"
}, // array of keys to look up values in the allModulesNeeded hashmap
chunkKeys, allModulesNeeded]); // add chunk registration code that will push all chunk requirements into webpack
// eslint-disable-next-line no-param-reassign
compilation.assets[fileName] = new ConcatSource(String("(window[\"webpackRegister\"] = window[\"webpackRegister\"] || []).push(".concat(pushArguments, ");\n")), compilation.assets[fileName]);
}
var loopFiles = mem(function (files) {
return files.filter(function (file) {
return file.includes(".css");
});
}); // eslint-disable-next-line import/prefer-default-export
function wrapChunks(compilation, chunks) {
// create a maps
var map = {
ignoredChunk: new Set()
};
var orgs = {}; // loop over each chunk
chunks.forEach(function (chunk) {
// map weak maps and weak sets for better organization & perf
// console.group(group)
// check if this chunk is an entrypoint or has the webpack runtime
// if it does, dont bother mapping registration data or include them in any other chunks registration maps
if (chunk.hasEntryModule() || chunk.hasRuntime()) {
map.ignoredChunk.add(chunk.id);
} else {} // dont run if this has already been done on the chunk
if (!chunk.rendered) {
return;
} // get all the modules in a chunk and loop over them
chunk.getModules().forEach(function (module) {
// add the chunk ID as a key and create an empty array if one isnt there already
if (!(map[chunk.id] instanceof Object)) {
map[chunk.id] = {
js: [],
css: []
};
} // push each module in a chunk into its array within the map
if (module.id) map[chunk.id].js.push("".concat(module.id));
map[chunk.id].css = [].concat(_toConsumableArray(map[chunk.id].css), _toConsumableArray(loopFiles(chunk.files))); // check the reason a chunk exists, this is an array which returns any and all modules that depend on the current module
module.reasons.forEach(function (reason) {
if (reason.module) {
// if theres a module, loop over the chunks this module is in
reason.module.chunksIterable.forEach(function (reasonChunk) {
// add the chunkID of where this module exists
if (!orgs[reasonChunk.id]) orgs[reasonChunk.id] = {
js: new Set(),
css: new Set()
};
orgs[reasonChunk.id].css = new Set([].concat(_toConsumableArray(orgs[reasonChunk.id].css), _toConsumableArray(loopFiles(reasonChunk.files)))); // console.log("reasonChunk", reasonChunk);
// orgs[chunk.id].add(`${module.id}-${module.rawRequest}`);
// add the chunkID that depends on this module
if (chunk.id) orgs[reasonChunk.id].js.add(chunk.id);
});
}
});
}); // loop over everything and add the all other chunks a chunk depends on.
// this creates a map telling us what a chunk needs and where to find it
// chunks usually wont contain ALL the dependencies they need, so i need to make sure that i record what files contain dependencies
// this chunk needs in order to be executed successfully
Object.keys(orgs).forEach(function (key) {
orgs[key].js.forEach(function (subSet) {
if (orgs[subSet]) {
var _orgs$subSet$js;
(_orgs$subSet$js = orgs[subSet].js)["delete"].apply(_orgs$subSet$js, _toConsumableArray(map.ignoredChunk)); // dont walk entry or runtime chunks
if (!map.ignoredChunk.has(subSet)) {
var _orgs$key$js, _orgs$key$css;
if (orgs[subSet].js.size) (_orgs$key$js = orgs[key].js).add.apply(_orgs$key$js, _toConsumableArray(orgs[subSet].js));
if (orgs[subSet].css.size) (_orgs$key$css = orgs[key].css).add.apply(_orgs$key$css, _toConsumableArray(orgs[subSet].css));
}
}
});
});
});
// to ensure the chunk maps are complete, i run another loop over the chunks - the previous loop creates a complete map
// this loop uses the completed map to write the chunk registration data into each chunk file
chunks.forEach(function (chunk) {
if (!chunk.rendered || map.ignoredChunk.has(chunk.id)) {
return;
} // loop over all files that make up this chunk
// eslint-disable-next-line no-restricted-syntax
var _iteratorNormalCompletion = true;
var _didIteratorError = false;
var _iteratorError = undefined;
try {
for (var _iterator = chunk.files[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {
var fileName = _step.value;
// check that its a javascript file (might be an image, html, css)
if (ModuleFilenameHelpers.matchObject({}, fileName) && fileName.indexOf(".js") !== -1) {
var _orgs$chunk$id;
// get all the chunksID's the current chunk might need
var AllChunksNeeded = Array.from((orgs === null || orgs === void 0 ? void 0 : (_orgs$chunk$id = orgs[chunk.id]) === null || _orgs$chunk$id === void 0 ? void 0 : _orgs$chunk$id.js) || new Set()); // create the final map which contains an array of chunkID as well as a object of chunk of what each chunk needs
var AllModulesNeeded = AllChunksNeeded.reduce(function (allDependencies, dependentChunk) {
return _objectSpread({}, allDependencies, _defineProperty({}, dependentChunk, {
js: _toConsumableArray(new Set(map[dependentChunk].js)),
css: _toConsumableArray(new Set(map[dependentChunk].css))
}));
}, {});
// now that we have maps of what the current file being iterated needs, write additional code to the file
wrapFile(compilation, fileName, AllModulesNeeded, AllChunksNeeded);
}
}
} catch (err) {
_didIteratorError = true;
_iteratorError = err;
} finally {
try {
if (!_iteratorNormalCompletion && _iterator["return"] != null) {
_iterator["return"]();
}
} finally {
if (_didIteratorError) {
throw _iteratorError;
}
}
}
});
}
+50
View File
@@ -0,0 +1,50 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.addInterleaveRequire = exports.addInterleaveExtension = void 0;
var Template = require("webpack/lib/Template");
var detachedPromise = function detachedPromise(promiseVar, resolverVar) {
return Template.asString(["var ".concat(promiseVar, " = new Promise(function (resolve, reject) {"), Template.indent([resolverVar, " = [resolve, reject];"]), "});"]);
};
var chunkPromise = Template.asString(["function chunkPromise(chunkName){", Template.indent(["var resolver;", detachedPromise("promise", "resolver"), // never overwrite existing promises
"if(!interleaveDeferred[chunkName])interleaveDeferred[chunkName] = {promise:promise, resolver:resolver};", "return true"]), "}"]);
/**
* addInterleaveExtension - adds a function to webpack runtime which helps register interleaved chunks requirements
* @param source - the _webpack_require_ source code, from webpack runtime
* @param options - the plugin options
* @returns {string}
*/
var addInterleaveExtension = function addInterleaveExtension(source, requireFn, _ref) {
var debug = _ref.debug;
return Template.asString([// get the current source template that holds webpack require
source, // add another function below webpack require, this function
// has access to any and all functions and variables within the webpack bootstrap
"// webpack chunk self registration", // TODO: use the interleave map added via localVars already within the runtime
"var interleaveDeferred = {};", "var interleaveDeferredCopy = {};", "var registeredResolver;", detachedPromise("allChunksRegistered", "registeredResolver"), // this is called whenever registerLocals window.webpackRegister.push is executed
// chunkMap is what the chunk pushes into the registration, containing the chunks build hash, chunk names and modules ids it needs
"function registerLocals(chunkMap) {", chunkPromise, Template.indent(["var options = chunkMap[0];", "var chunkDependencyKeys = chunkMap[1];", "var chunkModuleHashMap = chunkMap[2];", debug ? Template.asString(["console.log({", Template.indent(["chunkBelongsToThisBuild: compilationHash === options.hash,", "chunkCompileHash: options.hash,", "chunkDependencyKeys: chunkDependencyKeys,", "chunkModuleHashMap: chunkModuleHashMap,", "webpackModules: modules"]), "});"]) : "", // check if compilationHash (from webpack runtime) matches the hash the chunk is reporting, if it does then do nothing
// because the chunk isnt being interleaved, its being consumed by the app it actually belongs to
"if(compilationHash !== options.hash) {", // this still needs to be written, so its mostly logging at the moment - what goes here will be a mix of webpack functions instructing webpack to download urls
Template.indent([debug ? "console.group('chunkDependencyKeys Loop');" : "", "chunkDependencyKeys.forEach(function(chunkName){", Template.indent([// get css for chunk, if there is any.
"var cssChunks = chunkModuleHashMap[chunkName].css", debug ? Template.asString(["console.log({", Template.indent(["chunkName: chunkName,", "css: chunkModuleHashMap[chunkName].css,", "js: chunkModuleHashMap[chunkName].js,"]), "});"]) : "", // Loop over the modules a chunk depends on
"chunkModuleHashMap[chunkName].js.find(function(moduleId){", Template.indent(["if(!modules[moduleId]) {", debug ? "console.log('Module', moduleId, 'is missing from host build. Needs', chunkName);" : "", // as soon as a missing module is found, get the chunk that contains it from the origin build
Template.indent("return chunkPromise(chunkName)"), "}"]), "});", // TODO: use CSS cache to determine if must re-download
"if(cssChunks && cssChunks.length) {", Template.indent([// loop over css chunks attached to a chunk
"cssChunks.forEach(function(styleChunk){", debug ? "console.log('CSS', styleChunk, 'is missing from host build. Will download');" : "", Template.indent(["chunkPromise(styleChunk)"]), "});"]), "}"]), "})", debug ? "console.groupEnd();" : "", // resolve the promise
"registeredResolver[0]();"]), "}"]), "};"]);
}; // setting up async require capabilities
exports.addInterleaveExtension = addInterleaveExtension;
var addInterleaveRequire = function addInterleaveRequire(source, requireFn) {
return Template.asString([source, "", Template.getFunctionContent(require("./interleaveFn").requireInterleaveExtension).replace("__webpack__require__", requireFn)]);
};
exports.addInterleaveRequire = addInterleaveRequire;
+130
View File
@@ -0,0 +1,130 @@
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.mergeDeep = mergeDeep;
exports.removeNull = removeNull;
exports.getInterleaveConfig = void 0;
function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }
function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }
function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }
function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }
function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); }
var mem = require("mem");
var getInterleaveConfig = mem(function () {
var pkgUp = require("pkg-up").sync();
var packageJson;
if (pkgUp) {
// eslint-disable-next-line import/no-dynamic-require
packageJson = require(pkgUp);
}
return packageJson.interleave || null;
});
/* eslint-disable no-param-reassign */
exports.getInterleaveConfig = getInterleaveConfig;
function mergeDeep() {
var isObject = function isObject(obj) {
return obj && _typeof(obj) === "object";
};
for (var _len = arguments.length, objects = new Array(_len), _key = 0; _key < _len; _key++) {
objects[_key] = arguments[_key];
}
return objects.reduce(function (prev, obj) {
Object.keys(obj).forEach(function (key) {
var pVal = prev[key];
var oVal = obj[key];
if (Array.isArray(pVal) && Array.isArray(oVal)) {
prev[key] = pVal.concat.apply(pVal, _toConsumableArray(oVal));
} else if (isObject(pVal) && isObject(oVal)) {
prev[key] = mergeDeep(pVal, oVal);
} else {
prev[key] = oVal;
}
});
return prev;
}, {});
}
/* eslint-enable no-param-reassign */
// TODO: delete this function in V2
function removeNull() {
var nullCount = 0;
var length = this.length;
for (var i = 0, len = this.length; i < len; i++) {
if (!this[i]) {
nullCount++;
}
} // no item is null
if (!nullCount) {
return this;
} // all items are null
if (nullCount === length) {
this.length = 0;
return this;
} // mix of null // non-null
var idest = 0;
var isrc = length - 1;
length -= nullCount;
while (nullCount) {
while (!this[isrc]) {
isrc--;
nullCount--;
} // find a non null (source) slot on the right
if (!nullCount) {
break;
} // break if found all null
while (this[idest]) {
idest++;
} // find one null slot on the left (destination)
// perform copy
this[idest] = this[isrc];
if (! --nullCount) {
break;
}
idest++;
isrc--;
}
this.length = length;
return this;
} // eslint-disable-next-line no-extend-native
Object.defineProperty(Array.prototype, "removeNull", {
value: removeNull,
writable: true,
configurable: true
});