{"bugs":{"url":"https://github.com/ScriptedAlchemy/webpack-external-import/issues"},"dist":{"shasum":"bceccdafb9572931ee93ffa84e39eea9f6d15dca","tarball":"https://registry.npmjs.org/webpack-external-import/-/webpack-external-import-0.3.0-beta.0.tgz","fileCount":8,"integrity":"sha512-58uSxZEi1Y2HGktQficlwSVHcvml1p6fpXrFEMEgi8nR/eLWlHcoYyILGRzZFSq8jfFqhAbHlm4fcnAIVA5Epg==","signatures":[{"sig":"MEUCIQC7Ws3KyTIBKpdQn8RW2nqmBChRZQ8REfVfgWcR/JfOfwIgUGqXgC9k9TiWeOiTDhYjbvGtzxpvsNH/mTxDoYWijao=","keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA"}],"unpackedSize":95303,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJd3s4uCRA9TVsSAnZWagAAqHkP/jGBvLfPJuGoxMoOM2oI\n1yV9pP29nbe+QxThtMKBsJuchHFZlz4wXUD0o/JzEt4073rNOpjhu2LSq7tT\nP7UBqW23mbwimQ+yIf7xtP1tMLHfcO6Qy2340O4Zuo9IXHPouH1f153FVUqQ\ntw5TVs4EnnMgiNT4aCMgdTr1zWZI6FRICORgBj3CGhQBUGKLjuzwHf7lKczt\nQa0NMXtKgaVoeBF3qR9SXazuplXn9yEwxWEOivVe+pILrtrsM48aIQFVzSg7\nMU6I/HumHwyjQHVB5Wni2k+Rlu6BgYpzbWoiOCxMcrvm9CnukEj1VOkM2PeO\nxLdwCRUrToruspRjGHaL+uTRIqKn4lNj23Vy5FWZodatjuhpdgWcYa20Rmjt\nsBG8gdZdIm/koYDCtslhwGIHYhQSJT2zEkQT5gqLaLyCPAa24SSHG0c/KPN+\nH/kc2n6DnXdV0Xf6rknzst1K0CTeFyVr1N0eOWf4P6dgNG+5RVt0BE7qTVJF\nKm4pFFqWM6yl0sx8T1GPPoIVKp828qCUsyjyWj9vg2LJ3kRHdf2dAhlYn6Yd\nHS3RujI7XKPZNQLJlCc/ZFLq+sw2m9D7ZXi/vr+bvvFBIw854N5E/8GIFMhe\nJhCb168EYYaKw3LnpXCRJStuFWhA+Scg93Di0ebU77jckMH7EDzfucHQoHBZ\ncMl6\r\n=aJUU\r\n-----END PGP SIGNATURE-----\r\n"},"jest":{"preset":"jest-puppeteer"},"name":"webpack-external-import","babel":{"plugins":["@babel/plugin-proposal-optional-chaining"],"presets":["@babel/preset-env","@babel/preset-react"]},"author":{"url":"https://github.com/ScriptedAlchemy","name":"Zack Jackson","email":"zack@ScriptedAlchemy.com"},"config":{"commitizen":{"path":"./node_modules/cz-conventional-changelog"}},"readme":"# Webpack External Import\n> **import() URLs and other external resources from third parties, or other webpack builds themselves!**\n\n<p align=\"center\">\n    \n[![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)\n  <a href=\"https://www.npmjs.com/package/webpack-external-import\">\n    <img src=\"https://img.shields.io/npm/v/webpack-external-import.svg\" alt=\"Version\" />\n  </a>\n\n  <a href=\"https://www.npmjs.com/package/webpack-external-import\">\n    <img src=\"https://img.shields.io/npm/dt/webpack-external-import.svg\" alt=\"Downloads\" />\n  </a>\n\n  <a href=\"https://www.npmjs.com/package/webpack-external-import\">\n    <img src=\"https://img.shields.io/npm/dm/webpack-external-import.svg\" alt=\"License\" />\n  </a>\n  \n  <a href=\"https://www.npmjs.com/package/webpack-external-import\">\n    <img src=\"https://img.shields.io/npm/l/webpack-external-import.svg\" alt=\"License\" />\n  </a>\n</p>\n\n```shell\n$ yarn  webpack-external-import\n```\n*This project is under active development*\n\n**To jump to the _development_ section [click here](#development)\n\n\n\n# Installation\n\n### npm\n\n```sh\nnpm install webpack-external-import --save\n```\n\n### Yarn\n\n```sh\nyarn add webpack-external-import --save\n```\n\n## Getting Started\n\n1.  Add `webpack-external-import/webpack` to your webpack plugins:\n```js\n// techblog.webpack.config.js\nconst URLImportPlugin = require('webpack-external-import/webpack')\n{\n    plugins: [\n        new URLImportPlugin({\n          manifestName: 'website-one'\n        })\n    ]\n}\n```\n\n2. Add the `import()` polyfill (recommended)\n```js\n// index.js\nimport 'webpack-external-import/polyfill';\n\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport App from './App.jsx';\n\nReactDOM.render(<App />, document.getElementById('app'));\n```\n3. If you are interleaving webpack bundles, load their manifests\n```js\n  import {corsImport} from \"webpack-external-import\"\n  // if importing on the same domain and CORS isnt an issue\n  import(/* webpackIgnore:true */'http://localhost:3002/importManifest.js')\n\n  // if you need to import from a third party where CORS is an issue\n  corsImport('http://localhost:3002/importManifest.js')\n```\n4. import an external resource \nWe use raw `import()` with a polyfill to act as a script loader. We also have a fallback script loader for loading CORS. \n\n```js\n// App.jsx\n// import a chunk from another website build with webpack-external-import\n  import {corsImport} from \"webpack-external-import\"\n\n  componentDidMount() {\n      corsImport('http://localhost:3002/importManifest.js').then(() => {\n        this.setState({ manifestLoaded: true });\n        importDependenciesOf('http://localhost:3002', 'website-two', 'TitleComponent').then((url) => {\n          this.setState({ titleUrl: url });\n        });\n  \n        // if CORS isnt a problem, you can use native import (its polyfilled) \n        import(/* webpackIgnore:true */getChunkPath('http://localhost:3002', 'website-two', 'SomeExternalModule.js')).then(() => {\n          console.log('got module, will render it in 2 seconds');\n          setTimeout(() => {\n            this.setState({ loaded: true });\n          }, 2000);\n        });\n      });\n    }\n```\n\nOr with JSX and a react component\n```js\nimport {ExternalComponent, getChunkPath} from 'webpack-external-import'\n render() {\n    const { manifestLoaded } = this.state;\n\n    return (\n      <div>\n        <HelloWorld />\n        { manifestLoaded && <ExternalComponent src={getChunkPath('http://localhost:3002', 'website-two', 'TitleComponent.js')} module=\"TitleComponent\" export=\"Title\" title=\"Some Heading\" />}\n      </div>\n    );\n  }\n```\n\n## What is the use of  `webpack-external-import` ?\n\n- **Load components over the wire** - Pull in components at runtime.\n- **Build leaner micro-frontends (MFE)** - \nMicro-frontends can share bundle chunks and resources with each other while remaining self-contained, removing needless code duplication.\n- **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.\n- **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.\n- **LOSA Style frontend architecture** - Run multiple apps on a single page.\n- **FOSA Style frontend orchestration** - Powerful frontend orchestration, self-organizing application architecture. Many builds act as one\n\n\n### Advanced Setup - Injecting Webpack modules from another build\n\nUse the webpack plugin to inject webpack modules from another build into your build. \n\n_**Important**: Make sure manifestName_ is unique per webpack build.\nIf you have multiple builds, they all need to have a unique manifestName\n\n**webpack.config.js**\n```js\nconst URLImportPlugin = require('webpack-external-import/webpack')\n{\n    plugins: [\n        new URLImportPlugin({\n          manifestName: 'website-one'\n        })\n    ]\n}\n```\n\n\n## Example Usage\nPretend 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.\n\nTo do this, we add an `externalize` comment to the module. The Externalize magic comment tells the plugin to make the module available externally with the name `ExampleModule`:\n\n\n<table>\n<tr>\n<th>\n<!-- empty -->\n</th>\n<th>\nApplication A\n</th>\n<th>\nApplication B \n</th>\n</tr>\n<tr>\n\n<td>\n  <strong>Provider: Javascript Asset</strong>\n</td>\n\n<td>\n\n    \n```js\n// Title.js\n\nimport React from 'react';\n\nexport \n const Title = ({title}) => {\n  return title\n}\n\nexport \n const alert = (message) => {\n  alert(message)\n}\n\n\n/*externalize:ExampleModule*/\n```\n\n</td>\n\n</tr>\n<tr>\n\n<td>\n    <strong>\n        Provider: <br/>Code-Splits <br/>asset into title-cnk\n   </strong>\n</td>\n\n<td>\n\nempty\n<td>\n\n<td>empty<td>\n\n</tr>\n\n<tr>\n<td>\n    <strong>Consumer File</strong>\n</td>\n<td><!--        --></td>\n\n<td>\n\n```js\n    \n// App.js\n\nimport(/* webpackIgnore:true */'http://website1.com/js/ExampleModule.js')\n.then(()=>{\n  const ExampleModule = __webpack_require__(\"ExampleModule\");\n  ExampleModule.alert('custom alert')\n});\n    \n```\n\n</td>\n</tr>\n\n<tr>\n<td>\n    <strong>React Example</strong>\n</td>\n    \n<td><!--        --></td>\n\n<td>\n\n```js\nimport {\n  ExternalComponent\n} from 'webpack-external-import'\n\nconst SomeComponent = (props)=>{\n  return (\n    <ExternalComponent \n    src={\n      this.state.url\n    } \n    module=\"ExampleModule\"\n    export='Title' \n    title={'Some Heading'}\n       />\n  )\n}\n```\n</td>\n</tr>\n</table>\n\n\n## Explanation\n    \nPretend we have two separate apps that each have their own independent build. We want to share a module from one of our apps with the other.\n    \nTo do this, we add an externalize comment to the module. This tells the plugin to make the module available externally with the name `ExampleModule` and webpack will chunk this file into `dist/ExampleModule.js`\n\n```js\n// Title.js\n\nimport React from 'react';\n\nexport const Title = ({title}) => {\n  return (<h1>{title}</h1>)\n}\n\nexport const alert = (message) => {\n  alert(message)\n}\n\n\n/*externalize:ExampleModule*/\n\n```\n\nThe `ExampleModule` can now be pulled into our other app using `import`:\n\n```js\nimport(/* webpackIgnore:true */'http://website1.com/js/ExampleModule.js').then(({ExampleModule})=>{\n  ExampleModule.alert('custom alert')\n});\n```\n\nThere is also a React component, `ExternalComponent`, that can be useful for importing React components:\n\n```js\nimport {ExternalComponent} from 'webpack-external-import'\n\n()=>{\n  return (\n    <ExternalComponent src={helloWorldUrl} module=\"ExampleModule\" export='Title' title={'Some Heading'} cors/>\n  )\n}\n```\n\n## Full Example\n\n```js\n// WEBSITE-ONE\n//app.js\n\nimport React, {Component} from 'react';\nimport {hot} from 'react-hot-loader';\nimport HelloWorld from './components/hello-world';\nimport {ExternalComponent,corsImport} from 'webpack-external-import'\n\nclass App extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      titleUrl: null,\n      manifestLoaded: false,\n      loaded: false,\n    };\n  }\n\n  componentDidMount() {\n    corsImport('http://localhost:3002/importManifest.js').then(() => {\n      this.setState({ manifestLoaded: true });\n      importDependenciesOf('http://localhost:3002', 'website-two', 'TitleComponent').then((url) => {\n        this.setState({ titleUrl: url });\n      });\n\n      import(/* webpackIgnore:true */getChunkPath('http://localhost:3002', 'website-two', 'SomeExternalModule.js')).then(() => {\n        console.log('got module, will render it in 2 seconds');\n        setTimeout(() => {\n          this.setState({ loaded: true });\n        }, 2000);\n      });\n    });\n  }\n\n  renderDynamic = () => {\n    const { loaded } = this.state;\n    if (!loaded) return null;\n\n    return __webpack_require__('SomeExternalModule').default();\n  }\n\n  render() {\n    const { manifestLoaded, titleUrl } = this.state;\n    if (!manifestLoaded) {\n      return 'Loading...';\n    }\n\n\n    return (\n      <div>\n        <HelloWorld />\n        {titleUrl && <ExternalComponent src={titleUrl} module=\"TitleComponent\" export=\"Title\" title=\"Some Heading\" />}\n        {this.renderDynamic()}\n      </div>\n    );\n  }\n}\n\nexport default App\n\n//WEBSITE-TWO\n//App.js\nclass App extends Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      component: null\n    };\n  }\n\n  componentDidMount() {\n    import('./components/hello-world').then((HelloWorld) => {\n      this.setState({component: HelloWorld.default})\n    })\n  }\n\n  render() {\n    if (!this.state.component) return <div/>\n    const {component: HelloWorld} = this.state\n    return <HelloWorld title=\"Hello from React webpack\"/>;\n\n  }\n}\n\nexport default hot(module)(App);\n\n// Title.js\n\nimport React from 'react';\n\nexport const Title = ({title}) => {\n  return (<h1>{title}</h1>)\n}\n\n\n/*externalize:TitleComponent*/\n\n\n```\n\n## API:\n\n```js\n// webpack.config.js\n\nmodule.exports = {\n  output: {\n    publicPath\n  },\n  plugins: [\n    new URLImportPlugin(options)\n  ]\n}\n```\n\n### `options.fileName`\n\nType: `String`<br>\nDefault: `manifest.json`\n\nThe manifest filename in your output directory.\n\n### `options.publicPath`\n\nType: `String`\nDefault: `output.publicPath`\n\nA path prefix that will be added to values of the manifest.\n\n### `options.basePath`\n\nType: `String`\n\nA path prefix for all keys. Useful for including your output path in the manifest.\n\n\n### `options.writeToFileEmit`\n\nType: `Boolean`<br>\nDefault: `false`\n\nIf set to `true` will emit to build folder and memory in combination with `webpack-dev-server`\n\n\n### `options.seed`\n\nType: `Object`<br>\nDefault: `{}`\n\nA 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.\n\n### `options.filter`\n\nType: `Function(FileDescriptor): Boolean`\n\nFilter out files. [FileDescriptor typings](#filedescriptor)\n\n### `options.test`\n\nType: `Function(Object, FileDescriptor): Object`<br>\nDefault: `src`\n\nTest resource path to see if plugin should apply transformations\n\n\n### `options.map`\n\nType: `Function(FileDescriptor): FileDescriptor`\n\nModify files details before the manifest is created. [FileDescriptor typings](#filedescriptor)\n\n### `options.sort`\n\nType: `Function(FileDescriptor): number`\n\nSort files before they are passed to `generate`. [FileDescriptor typings](#filedescriptor)\n\n### `options.generate`\n\nType: `Function(Object, FileDescriptor): Object`<br>\nDefault: `(seed, files) => files.reduce((manifest, {name, path}) => ({...manifest, [name]: path}), seed)`\n\nCreate the manifest. It can return anything as long as it's serializable by `JSON.stringify`. [FileDescriptor typings](#filedescriptor)\n\n### `options.serialize`\n\nType: `Function(Object): string`<br>\nDefault: `(manifest) => JSON.stringify(manifest, null, 2)`\n\nOutput manifest file in a different format then json (i.e., yaml).\n\n### **ExternalComponent**\nReact Component\n\n#### **Props**:\n\n**`src`: string** - Import source URL\n\n**`module`: string** - Module name, must match what was declared using /*externalize:ExampleModule*/\n\n**`export`: string** - The named export to use as a component from the module being imported\n\n**`cors`: bool** - If asset is being loaded from a url which throws a CORS error. This will inject a script to the browser\n\n\n#### Usage\n```js\n<ExternalComponent src={helloWorldUrl} module=\"ExampleModule\" export='Title' title={'Some Heading'}/>\n```\n\n## FileDescriptor\n\n```ts\nFileDescriptor {\n  path: string;\n  name: string | null;\n  isInitial: boolean;\n  isChunk: boolean;\n  chunk?: Chunk;\n  isAsset: boolean;\n  isModuleAsset: boolean;\n}\n```\n\n### The entry manifest\n\nEach webpack build using the webpack plugin emits a manifest file to the build output directory.\n\nThe manifest allows you to find a chunk that you want, even if the name has been hashed.\n\nBelow is an example of using the manifest.\n\nIn 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. \n\n```js\n    componentDidMount() {\n      corsImport('http://localhost:3002/importManifest.js').then(() => {\n        this.setState({ manifestLoaded: true });\n        importDependenciesOf('http://localhost:3002', 'website-two', 'TitleComponent').then((url) => {\n          this.setState({ titleUrl: url });\n        });\n  \n        import(/* webpackIgnore:true */getChunkPath('http://localhost:3002', 'website-two', 'SomeExternalModule.js')).then(() => {\n          console.log('got module, will render it in 2 seconds');\n          setTimeout(() => {\n            this.setState({ loaded: true });\n          }, 2000);\n        });\n      });\n    }\n```\n\n## DEMO\nHow to start using the demo\nIn the *root directory*, run the following\n1) run `yarn install`\n2) run `yarn demo` from the root directory\n3) browse to [localhost:3001](http://localhost:3001)  or [localhost:3002](http://localhost:3002) \n\nThis command will install, all dependencies, build the source for the plugin, install the demo dependencies, run all builds and start serving\n\n## Development & Debugging\nHow to start the demo in debug mode, using node --inspect and connecting to a chrome debugger\n\n> This is mainly for debugging the webpack plugin\n \nIn the root directory, run the following\n1) `yarn install`\n2) `yarn demo:debug` from the root directory\n3) browse to [localhost:3001](http://localhost:3001)  or [localhost:3002](http://localhost:3002) \n\n**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)_\n\n\nOpen chrome dev tools and you should see the box highlighted below appear, click on it to connect to the webpack debugger \n![GitHub Logo](/docs/inspect.png)\n","gitHead":"159f33d0530dd24449b677451f1714b56b85f310","license":"GNU GPLv3","scripts":{"demo":"yarn && yarn && yarn link webpack-external-import && concurrently \"yarn compile\" \"yarn link\" \"yarn demo:one\"  \"yarn demo:two\"","jest":"NODE_ENV=test jest","lint":"eslint --ext .js,.ts,.tsx src --fix","test":"yarn  lint && yarn  tsc-test && yarn  jest","babel":"yarn compile && cd manual && yarn babel","commit":"npx git-cz","compile":"babel src -d .","jest:ci":"cross-env NODE_ENV=development jest","prepare":"yarn compile && cd manual && yarn","demo:one":"cd manual/Website1; yarn && yarn link webpack-external-import && yarn manual:dev","demo:two":"cd manual/Website2; yarn && yarn link webpack-external-import && yarn manual:dev","demo:fast":"yarn compile && yarn link && yarn demo:one:fast | yarn demo:two:fast","demo:prod":"yarn && yarn compile && yarn link && yarn demo:one:prod | yarn demo:two:prod","commitlint":"npx commitlint  --from=HEAD~1 || yarn commitlinterror","demo:debug":"npx kill-port 3200 | yarn && yarn && yarn link webpack-external-import && concurrently \"yarn compile\" \"yarn link\" \"yarn demo:one\"  \"yarn demo:two\"","demo:one:fast":"cd manual/Website1; yarn link webpack-external-import && yarn manual:dev","demo:one:prod":"cd manual/Website1; yarn && yarn link webpack-external-import && yarn manual:prod","demo:two:fast":"cd manual/Website2; yarn link webpack-external-import && yarn manual:dev","demo:two:prod":"cd manual/Website2; yarn && yarn link webpack-external-import && yarn manual:prod","commitlinterror":"echo \"$(tput setaf 1)Red text $(tput setab 7)and white background$(tput sgr 0)\"","semantic-release":"semantic-release"},"_npmUser":{"name":"zackljackson","email":"zackary.l.jackson@gmail.com"},"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"],"repository":{"url":"git+https://github.com/ScriptedAlchemy/webpack-external-import.git","type":"git"},"_npmVersion":"6.9.0","description":"dynamic import() external urls!","directories":{},"maintainers":[{"name":"zackljackson","email":"zackary.l.jackson@gmail.com"}],"_nodeVersion":"10.16.0","dependencies":{"loadjs":"^3.6.1","dimport":"^1.0.0","fs-extra":"^8.1.0"},"_hasShrinkwrap":false,"readmeFilename":"README.md","devDependencies":{"jest":"^24.9.0","react":"16.8.6","eslint":"^6.4.0","webpack":"^4.40.2","cross-env":"^6.0.0","puppeteer":"^1.20.0","react-dom":"16.8.6","@babel/cli":"^7.6.0","babel-core":"^7.0.0-bridge.0","commitizen":"^4.0.3","prop-types":"^15.7.2","source-map":"^0.7.3","@babel/core":"^7.6.0","babel-watch":"^7.0.0","webpack-cli":"^3.3.9","babel-eslint":"^10.0.3","babel-loader":"^8.0.6","concurrently":"^4.1.2","jest-resolve":"^24.9.0","jest-haste-map":"^24.9.0","jest-puppeteer":"^4.3.0","@babel/traverse":"^7.7.4","semantic-release":"^15.13.24","@babel/preset-env":"^7.6.0","webpack-dev-server":"^3.8.1","@babel/preset-react":"^7.0.0","eslint-plugin-react":"^7.14.3","html-webpack-plugin":"^3.2.0","regenerator-runtime":"^0.13.3","eslint-config-airbnb":"^18.0.1","eslint-plugin-import":"^2.18.2","eslint-plugin-jsx-a11y":"^6.2.3","cz-conventional-changelog":"^3.0.2","@babel/helper-module-imports":"^7.0.0","@babel/plugin-transform-runtime":"^7.6.0","@typescript-eslint/eslint-plugin":"^2.3.0","@babel/plugin-transform-react-jsx":"^7.3.0","@babel/plugin-syntax-dynamic-import":"^7.2.0","@babel/plugin-proposal-class-properties":"^7.5.5","@babel/plugin-proposal-optional-chaining":"^7.6.0"},"peerDependencies":{"webpack":"^4.40.2"},"_npmOperationalInternal":{"tmp":"tmp/webpack-external-import_0.3.0-beta.0_1574882861890_0.9189392716832085","host":"s3://npm-registry-packages"},"_id":"webpack-external-import@0.3.0-beta.0","version":"0.3.0-beta.0"}