Skip to content
Merged
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
4 changes: 3 additions & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,7 @@
"browser": true,
"es6": true
},
"extends": "airbnb"
"extends": "airbnb",
"rules": {
}
}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ index.js
corsImport.js
polyfill.js
react.js
utils.js
yarn-error.log
6 changes: 2 additions & 4 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,5 @@ jobs:
script: npx travis-github-status
name: Linting
script: npm run lint
name: Snyk
script: snyk
#after_success:
# - npm run semantic-release
after_success:
- npm run semantic-release
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"scripts": {
"compile": "babel src -d .",
"test": "yarn lint && yarn tsc-test && yarn jest",
"lint": "eslint --ext .js,.ts,.tsx --ignore-pattern dist,node_modules . --fix",
"lint": "eslint --ext .js,.ts,.tsx src --fix",
"jest": "NODE_ENV=test jest",
"jest:ci": "cross-env NODE_ENV=development jest",
"demo:one": "cd manual/Website1; yarn && yarn link webpack-external-import && yarn manual:dev",
Expand Down
8 changes: 4 additions & 4 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ export const getChunkDependencies = (basePath, nameSpace, module) => {
&& window?.entryManifest[nameSpace][module].dependencies) {
window.entryManifest[nameSpace][module].dependencies.forEach((file) => {
if (!__webpack_modules__[file.id]) {
file.sourceFiles.forEach(chunkFile => dependencyPaths.push(basePath + chunkFile));
file.sourceFiles.forEach((chunkFile) => dependencyPaths.push(basePath + chunkFile));
}
});
} else if (window?.entryManifest[nameSpace]
&& window?.entryManifest[nameSpace][`${module}.js`]
&& window?.entryManifest[nameSpace][`${module}.js`].dependencies) {
window.entryManifest[nameSpace][`${module}.js`].dependencies.forEach((file) => {
if (!__webpack_modules__[file.id]) {
file.sourceFiles.forEach(chunkFile => dependencyPaths.push(basePath + chunkFile));
file.sourceFiles.forEach((chunkFile) => dependencyPaths.push(basePath + chunkFile));
}
});
}
Expand All @@ -47,8 +47,8 @@ export const getChunkDependencies = (basePath, nameSpace, module) => {

function getInSequence(array, asyncFunc) {
return array.reduce((previous, current) => (
previous.then(accumulator => (
asyncFunc(current).then(result => accumulator.concat(result))
previous.then((accumulator) => (
asyncFunc(current).then((result) => accumulator.concat(result))
))
), Promise.resolve([]));
}
Expand Down
79 changes: 33 additions & 46 deletions src/react.js
Original file line number Diff line number Diff line change
@@ -1,67 +1,54 @@
import React, { Component } from 'react';
import React, {
Component, useCallback, useEffect, useState,
} from 'react';
import PropTypes from 'prop-types';
import './polyfill';
import { importWithDependencies, importDependenciesOf } from './index';

class ExternalComponent extends Component {
constructor(props) {
super(props);

this.state = {
loaded: false,
};
this.importPromise = this.importPromise.bind(this);
this.Component = null;
}

importPromise(src) {
if (!src) {
return new Promise((resolve, reject) => {
reject();
const ExternalComponent = (props) => {
const {
src, module, export: exportName, cors, ...rest
} = props;
let Component = null;
const [loaded, setLoaded] = useState(false);
const importPromise = useCallback(
() => {
if (!src) return Promise.reject();
if (cors) {
return require('./corsImport').default(src);
}
return new Promise((resolve) => {
resolve(new Function(`return import("${src}")`)());
});
}
if (this.props.cors) {
return require('./corsImport').default(src);
}
},
[src, cors],
);

return new Promise((resolve) => {
resolve(new Function(`return import("${src}")`)());
});
}

componentDidMount() {
useEffect(() => {
require('./polyfill');

const { src, module, export: exportName } = this.props;
if (!src) {
throw new Error(`dynamic-import: no url ${JSON.stringify(this.props, null, 2)}`);
throw new Error(`dynamic-import: no url ${JSON.stringify(props, null, 2)}`);
}

this.importPromise(src).then(() => {
importPromise(src).then(() => {
const requiredComponent = __webpack_require__(module);
this.Component = requiredComponent.default ? requiredComponent.default : requiredComponent[exportName];
this.setState({ loaded: true });
Component = requiredComponent.default ? requiredComponent.default : requiredComponent[exportName];
setLoaded(true);
}).catch((e) => {
throw new Error(`dynamic-import: ${e.message}`);
});
}
}, []);

render() {
const { Component } = this;
const { loaded } = this.state;
if (!loaded) return null;

const { src, module, ...rest } = this.props;
return (
<Component {...rest} />
);
}
}
if (!loaded) return null;
return (
<Component {...rest} />
);
};

ExternalComponent.propTypes = {
src: PropTypes.oneOfType([PropTypes.func, PropTypes.object, PropTypes.string]).isRequired,
module: PropTypes.string,
module: PropTypes.string.isRequired,
cors: PropTypes.bool,
export: PropTypes.string,
};

export default ExternalComponent;
13 changes: 6 additions & 7 deletions src/webpack/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ const fs = require('fs');


function mergeDeep(...objects) {
const isObject = obj => obj && typeof obj === 'object';
const isObject = (obj) => obj && typeof obj === 'object';

return objects.reduce((prev, obj) => {
Object.keys(obj).forEach((key) => {
Expand Down Expand Up @@ -60,10 +60,9 @@ function hasExternalizedModule(module) {
return false;
}

const interleaveConfig = test => ({
const interleaveConfig = (test) => ({
test(module) {
if (module.resource) {
console.log(test, module.resource.includes(test), !!hasExternalizedModule(module));
return module.resource.includes(test) && !!hasExternalizedModule(module);
}
},
Expand Down Expand Up @@ -97,7 +96,7 @@ class URLImportPlugin {
);
}

this.opts = Object.assign({
this.opts = {
publicPath: null,
debug: debug || false,
testPath: 'src',
Expand All @@ -115,12 +114,13 @@ class URLImportPlugin {
context: null,
sort: null,
hashFunction: 'md4',
serialize: manifest => `if(!window.entryManifest) {window.entryManifest = {}}; window.entryManifest["${opts.manifestName}"] = ${JSON.stringify(
serialize: (manifest) => `if(!window.entryManifest) {window.entryManifest = {}}; window.entryManifest["${opts.manifestName}"] = ${JSON.stringify(
manifest,
null,
2,
)}`,
}, opts || {});
...opts || {},
};
}

getFileType(str) {
Expand Down Expand Up @@ -281,7 +281,6 @@ class URLImportPlugin {

if (module && module.files) {
if (dependencyChains[chunk.id]) {
// console.log({ files: module.files });
dependencyChainMap.sourceFiles = dependencyChainMap?.sourceFiles?.concat?.(module.files) || null;
} else {
// Object.assign(dependencyChains, { [chunk.id]: module.files });
Expand Down
113 changes: 113 additions & 0 deletions utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"use strict";

Object.defineProperty(exports, "__esModule", {
value: true
});
exports.importDependenciesOf = exports.importWithDependencies = exports.getChunkDependencies = exports.getChunkPath = void 0;

var _isUrlSuperb = _interopRequireDefault(require("is-url-superb"));

var _corsImport = _interopRequireDefault(require("./corsImport"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

var getChunkPath = function getChunkPath(basePath, nameSpace, module) {
var _window, _window2, _window3, _window4, _window5, _window6;

if (!window.entryManifest) return;
if (!nameSpace) return;
if (!window.entryManifest[nameSpace]) return;
var pathString = [];

if (((_window = window) === null || _window === void 0 ? void 0 : _window.entryManifest[nameSpace]) && ((_window2 = window) === null || _window2 === void 0 ? void 0 : _window2.entryManifest[nameSpace][module]) && ((_window3 = window) === null || _window3 === void 0 ? void 0 : _window3.entryManifest[nameSpace][module].path)) {
pathString = [basePath, window.entryManifest[nameSpace][module].path];
} else if (((_window4 = window) === null || _window4 === void 0 ? void 0 : _window4.entryManifest[nameSpace]) && ((_window5 = window) === null || _window5 === void 0 ? void 0 : _window5.entryManifest[nameSpace]["".concat(module, ".js")]) && ((_window6 = window) === null || _window6 === void 0 ? void 0 : _window6.entryManifest[nameSpace]["".concat(module, ".js")].path)) {
pathString = [basePath, window.entryManifest[nameSpace]["".concat(module, ".js")].path];
}

return pathString.join('');
};

exports.getChunkPath = getChunkPath;

var getChunkDependencies = function getChunkDependencies(basePath, nameSpace, module) {
var _window7, _window8, _window9, _window11, _window12, _window13;

if (!window.entryManifest) return;
if (!nameSpace) return;
if (!window.entryManifest[nameSpace]) return;
var dependencyPaths = [];

if (((_window7 = window) === null || _window7 === void 0 ? void 0 : _window7.entryManifest[nameSpace]) && ((_window8 = window) === null || _window8 === void 0 ? void 0 : _window8.entryManifest[nameSpace][module]) && ((_window9 = window) === null || _window9 === void 0 ? void 0 : _window9.entryManifest[nameSpace][module].dependencies)) {
window.entryManifest[nameSpace][module].dependencies.forEach(function (file) {
if (!__webpack_modules__[file.id]) {
file.sourceFiles.forEach(function (chunkFile) {
var _window10;

return dependencyPaths.push(basePath + ((_window10 = window) === null || _window10 === void 0 ? void 0 : _window10.entryManifest[nameSpace][chunkFile].path));
});
}
});
} else if (((_window11 = window) === null || _window11 === void 0 ? void 0 : _window11.entryManifest[nameSpace]) && ((_window12 = window) === null || _window12 === void 0 ? void 0 : _window12.entryManifest[nameSpace]["".concat(module, ".js")]) && ((_window13 = window) === null || _window13 === void 0 ? void 0 : _window13.entryManifest[nameSpace]["".concat(module, ".js")].dependencies)) {
window.entryManifest[nameSpace]["".concat(module, ".js")].dependencies.forEach(function (file) {
if (!__webpack_modules__[file.id]) {
file.sourceFiles.forEach(function (chunkFile) {
var _window14;

return dependencyPaths.push(basePath + ((_window14 = window) === null || _window14 === void 0 ? void 0 : _window14.entryManifest[nameSpace][chunkFile].path));
});
}
});
}

return Array.from(new Set(dependencyPaths));
};

exports.getChunkDependencies = getChunkDependencies;

function getInSequence(array, asyncFunc) {
return array.reduce(function (previous, current) {
return previous.then(function (accumulator) {
return asyncFunc(current).then(function (result) {
return accumulator.concat(result);
});
});
}, Promise.resolve([]));
}

var nativeImport = function nativeImport(src) {
return new Promise(function (resolve, reject) {
if ((0, _isUrlSuperb["default"])(src)) {
resolve(new Function("return import(\"".concat(src, "\")"))());
} else {
reject('webpack-external-import: nativeImport - invalid URL');
}
});
};

var importWithDependencies = function importWithDependencies(basePath, nameSpace, module) {
var cors = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
if (!window.entryManifest) return;
if (!nameSpace) return;
if (!window.entryManifest[nameSpace]) return;
var importFunction = cors ? nativeImport : _corsImport["default"];
return getInSequence(getChunkDependencies(basePath, nameSpace, module), importFunction).then(function () {
return importFunction(getChunkPath(basePath, nameSpace, module));
});
};

exports.importWithDependencies = importWithDependencies;

var importDependenciesOf = function importDependenciesOf(basePath, nameSpace, module) {
var cors = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;
if (!window.entryManifest) return;
if (!nameSpace) return;
if (!window.entryManifest[nameSpace]) return;
var importFunction = cors ? nativeImport : _corsImport["default"];
return getInSequence(getChunkDependencies(basePath, nameSpace, module), importFunction).then(function () {
return getChunkPath(basePath, nameSpace, module);
}); // window.entryManifest[nameSpace][module]
// console.log('import with deps:')
};

exports.importDependenciesOf = importDependenciesOf;