├── .babelrc
├── .circleci
└── config.yml
├── .editorconfig
├── .eslintignore
├── .eslintrc
├── .gitattributes
├── .github
├── ISSUE_TEMPLATE.md
└── PULL_REQUEST_TEMPLATE.md
├── .gitignore
├── .jestrc
├── CHANGELOG.md
├── LICENSE
├── LICENSE_ORIGINAL
├── README.md
├── package-lock.json
├── package.json
├── src
├── Error.js
├── cjs.js
├── index.js
├── options.json
└── worklets
│ ├── InlineWorklet.js
│ └── index.js
└── test
├── Errors.test.js
├── __snapshots__
└── Errors.test.js.snap
├── fixtures
├── inline-fallbacks
│ ├── entry.js
│ ├── w1.js
│ └── w2.js
├── inline-options
│ ├── entry.js
│ ├── w1.js
│ └── w2.js
├── inline-query
│ ├── entry.js
│ └── worker.js
├── name-options
│ ├── entry.js
│ ├── w1.js
│ └── w2.js
├── name-query
│ ├── entry.js
│ └── worker.js
├── no-fallbacks
│ ├── entry.js
│ ├── w1.js
│ └── w2.js
├── nodejs-core-modules
│ ├── entry.js
│ └── worker.js
├── public-path-override
│ ├── entry.js
│ └── worker.js
└── worker
│ ├── entry.js
│ └── worker.js
├── helpers
└── compiler.js
└── loader.test.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | [
4 | "@babel/preset-env",
5 | {
6 | "targets": {
7 | "node": "6.9.0"
8 | }
9 | }
10 | ],
11 | ],
12 | "env": {
13 | "test": {
14 | "presets": [
15 | "@babel/preset-env",
16 | ],
17 | }
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/.circleci/config.yml:
--------------------------------------------------------------------------------
1 | unit_tests: &unit_tests
2 | steps:
3 | - checkout
4 | - setup_remote_docker
5 | - restore_cache:
6 | key: dependency-cache-{{ checksum "package-lock.json" }}
7 | - run:
8 | name: NPM Rebuild
9 | command: npm install
10 | - run:
11 | name: Run unit tests.
12 | command: npm run ci:test
13 | # canary_tests: &canary_tests
14 | # steps:
15 | # - checkout
16 | # - setup_remote_docker
17 | # - restore_cache:
18 | # key: dependency-cache-{{ checksum "package-lock.json" }}
19 | # - run:
20 | # name: NPM Rebuild
21 | # command: npm install
22 | # - run:
23 | # name: Install Webpack Canary
24 | # command: npm i --no-save webpack@next
25 | # - run:
26 | # name: Run unit tests.
27 | # command: npm run ci:test
28 |
29 | version: 2
30 | jobs:
31 | dependency_cache:
32 | docker:
33 | - image: webpackcontrib/circleci-node-base:latest
34 | steps:
35 | - checkout
36 | - setup_remote_docker
37 | - restore_cache:
38 | key: dependency-cache-{{ checksum "package-lock.json" }}
39 | - run:
40 | name: Install Dependencies
41 | command: npm install
42 | - save_cache:
43 | key: dependency-cache-{{ checksum "package-lock.json" }}
44 | paths:
45 | - ./node_modules
46 |
47 | node8-latest:
48 | docker:
49 | - image: webpackcontrib/circleci-node8:latest
50 | steps:
51 | - checkout
52 | - setup_remote_docker
53 | - restore_cache:
54 | key: dependency-cache-{{ checksum "package-lock.json" }}
55 | - run:
56 | name: NPM Rebuild
57 | command: npm install
58 | - run:
59 | name: Run unit tests.
60 | command: npm run ci:coverage
61 | - run:
62 | name: Submit coverage data to codecov.
63 | command: bash <(curl -s https://codecov.io/bash)
64 | when: on_success
65 | node6-latest:
66 | docker:
67 | - image: webpackcontrib/circleci-node6:latest
68 | <<: *unit_tests
69 | node9-latest:
70 | docker:
71 | - image: webpackcontrib/circleci-node9:latest
72 | <<: *unit_tests
73 | # node8-canary:
74 | # docker:
75 | # - image: webpackcontrib/circleci-node8:latest
76 | # <<: *canary_tests
77 | analysis:
78 | docker:
79 | - image: webpackcontrib/circleci-node-base:latest
80 | steps:
81 | - checkout
82 | - setup_remote_docker
83 | - restore_cache:
84 | key: dependency-cache-{{ checksum "package-lock.json" }}
85 | - run:
86 | name: NPM Rebuild
87 | command: npm install
88 | - run:
89 | name: Run linting.
90 | command: npm run lint
91 | - run:
92 | name: Run NSP Security Check.
93 | command: npm run security
94 | # - run:
95 | # name: Validate Commit Messages
96 | # command: npm run ci:lint:commits
97 | publish:
98 | docker:
99 | - image: webpackcontrib/circleci-node-base:latest
100 | steps:
101 | - checkout
102 | - setup_remote_docker
103 | - restore_cache:
104 | key: dependency-cache-{{ checksum "package-lock.json" }}
105 | - run:
106 | name: NPM Rebuild
107 | command: npm install
108 | - run:
109 | name: Validate Commit Messages
110 | command: npm run release:validate
111 | - run:
112 | name: Publish to NPM
113 | command: printf "noop running conventional-github-releaser"
114 |
115 | version: 2.0
116 | workflows:
117 | version: 2
118 | validate-publish:
119 | jobs:
120 | - dependency_cache
121 | - node6-latest:
122 | requires:
123 | - dependency_cache
124 | filters:
125 | tags:
126 | only: /.*/
127 | - analysis:
128 | requires:
129 | - dependency_cache
130 | filters:
131 | tags:
132 | only: /.*/
133 | - node8-latest:
134 | requires:
135 | - analysis
136 | - node6-latest
137 | filters:
138 | tags:
139 | only: /.*/
140 | - node9-latest:
141 | requires:
142 | - analysis
143 | - node6-latest
144 | filters:
145 | tags:
146 | only: /.*/
147 | # - node8-canary:
148 | # requires:
149 | # - analysis
150 | # - node6-latest
151 | filters:
152 | tags:
153 | only: /.*/
154 | - publish:
155 | requires:
156 | - node8-latest
157 | - node9-latest
158 | filters:
159 | branches:
160 | only:
161 | - master
162 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 |
3 | [*]
4 | charset = utf-8
5 | indent_style = space
6 | indent_size = 2
7 | end_of_line = lf
8 | insert_final_newline = true
9 | trim_trailing_whitespace = true
10 |
11 | [.md]
12 | insert_final_newline = false
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | test/fixtures
2 | test/__expected__
3 |
4 | src/worklets/InlineWorklet.js
5 |
6 | /node_modules
7 | /dist
8 |
--------------------------------------------------------------------------------
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "webpack"
3 | }
4 |
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | package-lock.json -diff
2 | * text=auto
3 | bin/* eol=lf
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
8 |
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | logs
2 | *.log
3 | npm-debug.log*
4 | .eslintcache
5 | /coverage
6 | /dist
7 | /local
8 | /reports
9 | /node_modules
10 | /test/__expected__
11 | .DS_Store
12 | Thumbs.db
13 | .idea
14 | .vscode
15 | *.sublime-project
16 | *.sublime-workspace
17 |
--------------------------------------------------------------------------------
/.jestrc:
--------------------------------------------------------------------------------
1 | {
2 | "testEnvironment": "node"
3 | }
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # Change Log
2 |
3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.
4 |
5 |
6 | ## [1.1.1](https://github.com/webpack-contrib/worker-loader/compare/v1.1.0...v1.1.1) (2018-02-25)
7 |
8 |
9 | ### Bug Fixes
10 |
11 | * **index:** add `webpack >= v4.0.0` support ([#128](https://github.com/webpack-contrib/worker-loader/issues/128)) ([d1a7a94](https://github.com/webpack-contrib/worker-loader/commit/d1a7a94))
12 |
13 |
14 |
15 |
16 | # [1.1.0](https://github.com/webpack-contrib/worker-loader/compare/v1.0.0...v1.1.0) (2017-10-24)
17 |
18 |
19 | ### Features
20 |
21 | * add `publicPath` support (`options.publicPath`) ([#31](https://github.com/webpack-contrib/worker-loader/issues/31)) ([96c6144](https://github.com/webpack-contrib/worker-loader/commit/96c6144))
22 |
23 |
24 |
25 |
26 | ## [1.0.0](https://github.com/webpack-contrib/worker-loader/compare/v0.8.0...v1.0.0) (2017-09-25)
27 |
28 |
29 | ### Features
30 |
31 | * add `options` validation (`schema-utils`) ([#78](https://github.com/webpack-contrib/worker-loader/issues/78)) ([5e2f5e6](https://github.com/webpack-contrib/worker-loader/commit/5e2f5e6))
32 | * support loading node core modules ([#76](https://github.com/webpack-contrib/worker-loader/issues/76)) ([edcda35](https://github.com/webpack-contrib/worker-loader/commit/edcda35))
33 |
34 |
35 | ### BREAKING CHANGES
36 |
37 | * loader-utils upgrade to > 1.0 is not backwards
38 | compatible with previous versions
39 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Additions and modifications to `worker-loader` copyright (c) 2018 Walker Henderson
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | 'Software'), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/LICENSE_ORIGINAL:
--------------------------------------------------------------------------------
1 | Copyright JS Foundation and other contributors
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining
4 | a copy of this software and associated documentation files (the
5 | 'Software'), to deal in the Software without restriction, including
6 | without limitation the rights to use, copy, modify, merge, publish,
7 | distribute, sublicense, and/or sell copies of the Software, and to
8 | permit persons to whom the Software is furnished to do so, subject to
9 | the following conditions:
10 |
11 | The above copyright notice and this permission notice shall be
12 | included in all copies or substantial portions of the Software.
13 |
14 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Worklet Loader
2 | This loader loads imported scripts as a URL pointing to (or containing) a compiled module. That URL can be used to add worklet modules.
3 |
4 | **NOTE! At the moment, this is basically just a fork of [`worker-loader`](https://github.com/webpack-contrib/worker-loader) and *probably shouldn't be used*. It's possible that, at some point, `worker-loader` will support worklets and this loader will be obsolete. It's also possible that there are worker-specific things that this package does that breaks worklets for one reason or another. So be careful!**
5 |
6 | ## Install
7 |
8 | ```bash
9 | npm i -D worklet-loader
10 | ```
11 |
12 | ## [Usage](https://webpack.js.org/concepts/loaders)
13 |
14 | ### `Inlined`
15 |
16 | **App.js**
17 | ```js
18 | import workletUrl from 'worklet-loader!./Worklet.js';
19 | ```
20 |
21 | ### `Config`
22 |
23 | **webpack.config.js**
24 | ```js
25 | {
26 | module: {
27 | rules: [
28 | {
29 | test: /\.worklet\.js$/,
30 | use: { loader: 'worklet-loader' }
31 | }
32 | ]
33 | }
34 | }
35 | ```
36 |
37 | **App.js**
38 | ```js
39 | import workletUrl from './file.worklet.js';
40 |
41 | const audioCtx = new AudioContext();
42 |
43 | audioCtx.audioWorklet.addModule(workletUrl).then(() => {
44 | // Do stuff with the now-registered processor
45 | });
46 | ```
47 |
48 | ## Options
49 |
50 | |Name|Type|Default|Description|
51 | |:--:|:--:|:-----:|:----------|
52 | |[**`name`**](#name)|`{String}`|`[hash].worklet.js`|Set a custom name for the output script|
53 | |[**`inline`**](#inline)|`{Boolean}`|`false`|Inline the worklet as a Blob|
54 | |[**`publicPath`**](#publicPath)|`{String}`|`null`|Override the path from which worklet scripts are downloaded|
55 |
56 | ### `name`
57 |
58 | To set a custom name for the output script, use the `name` parameter. The name may contain the string `[hash]`, which will be replaced with a content dependent hash for caching purposes. When using `name` alone `[hash]` is omitted.
59 |
60 | *webpack.config.js**
61 | ```js
62 | {
63 | loader: 'worklet-loader',
64 | options: { name: 'WorkerName.[hash].js' }
65 | }
66 | ```
67 |
68 | ### `inline`
69 |
70 | Inline the worklet as a `Blob` with the `inline` parameter
71 |
72 | **webpack.config.js**
73 | ```js
74 | {
75 | loader: 'worklet-loader',
76 | options: { inline: true }
77 | }
78 | ```
79 |
80 | ### `publicPath`
81 |
82 | Overrides the path from which worklet scripts are downloaded. If not specified, the same public path used for other
83 | webpack assets is used
84 |
85 | **webpack.config.js**
86 | ```js
87 | {
88 | loader: 'worklet-loader'
89 | options: { publicPath: '/scripts/worklets/' }
90 | }
91 | ```
92 |
93 | ## Examples
94 |
95 | ### Integrating with TypeScript
96 |
97 | You will need to define a custom module for the exports of your worklet files
98 |
99 | **typings/custom.d.ts**
100 | ```typescript
101 | declare module "*.worklet.ts" {
102 | const exportString: string;
103 | export default exportString;
104 | }
105 | ```
106 |
107 | **App.ts**
108 | ```typescript
109 | import fooBarWorkletUrl from 'worlet-loader!./fooBar.worklet.ts'
110 |
111 | const audioCtx = new AudioContext();
112 |
113 | // @ts-ignore: AudioContext.audioWorklet is not available as a type yet
114 | audioCtx.audioWorklet.addModule(fooBarWorkletUrl).then(() => {
115 | // Do stuff with the now-registered processor
116 | });
117 | ```
118 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "worklet-loader",
3 | "version": "2.0.0",
4 | "author": "Walker Henderson",
5 | "description": "worklet loader module for webpack",
6 | "repository": "https://github.com/reklawnos/worklet-loader.git",
7 | "bugs": "https://github.com/reklawnos/worklet-loader/issues",
8 | "homepage": "https://github.com/reklawnos/worklet-loader",
9 | "license": "MIT",
10 | "main": "dist/cjs.js",
11 | "files": [
12 | "dist"
13 | ],
14 | "scripts": {
15 | "start": "npm run build -- -w",
16 | "build": "cross-env NODE_ENV=production babel src -d dist --ignore 'src/**/*.test.js' --copy-files",
17 | "clean": "del-cli dist",
18 | "lint": "eslint --cache src test",
19 | "lint-staged": "lint-staged",
20 | "prebuild": "npm run clean",
21 | "prepare": "npm run build",
22 | "release": "standard-version",
23 | "security": "nsp check",
24 | "test": "jest",
25 | "test:watch": "jest --watch",
26 | "test:coverage": "jest --collectCoverageFrom='src/**/*.js' --coverage",
27 | "ci:lint": "npm run lint && npm run security",
28 | "ci:test": "npm run test -- --runInBand",
29 | "ci:coverage": "npm run test:coverage -- --runInBand",
30 | "defaults": "webpack-defaults",
31 | "webpack-defaults": "webpack-defaults"
32 | },
33 | "dependencies": {
34 | "hoek": "^4.2.1",
35 | "loader-utils": "^1.0.0",
36 | "schema-utils": "^0.4.0"
37 | },
38 | "devDependencies": {
39 | "@babel/cli": "^7.14.5",
40 | "@babel/core": "^7.14.6",
41 | "@babel/preset-env": "^7.14.7",
42 | "babel-jest": "^27.0.6",
43 | "cross-env": "^5.0.0",
44 | "del": "^3.0.0",
45 | "del-cli": "^1.0.0",
46 | "eslint": "^4.0.0",
47 | "eslint-config-webpack": "^1.0.0",
48 | "eslint-plugin-import": "^2.2.0",
49 | "jest": "^27.0.6",
50 | "lint-staged": "^4.0.0",
51 | "nsp": "^2.6.0",
52 | "pre-commit": "^1.0.0",
53 | "standard-version": "^4.0.0",
54 | "webpack": "^3.0.0",
55 | "webpack-defaults": "^1.6.0"
56 | },
57 | "peerDependencies": {
58 | "webpack": "^3.0.0 || ^4.0.0-alpha.0 || ^4.0.0"
59 | },
60 | "engines": {
61 | "node": ">= 6.9.0 || >= 8.9.0"
62 | },
63 | "pre-commit": "lint-staged",
64 | "lint-staged": {
65 | "*.js": [
66 | "eslint --fix",
67 | "git add"
68 | ]
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/Error.js:
--------------------------------------------------------------------------------
1 | class LoaderError extends Error {
2 | constructor(err) {
3 | super(err);
4 |
5 | this.name = err.name || 'Loader Error';
6 | this.message = `${err.name}\n\n${err.message}\n`;
7 | this.stack = false;
8 | }
9 | }
10 |
11 | export default LoaderError;
12 |
--------------------------------------------------------------------------------
/src/cjs.js:
--------------------------------------------------------------------------------
1 | const loader = require('./index');
2 |
3 | module.exports = loader.default;
4 | module.exports.pitch = loader.pitch;
5 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable
2 | import/first,
3 | import/order,
4 | comma-dangle,
5 | linebreak-style,
6 | no-param-reassign,
7 | no-underscore-dangle,
8 | prefer-destructuring
9 | */
10 | import schema from './options.json';
11 | import loaderUtils from 'loader-utils';
12 | import validateOptions from 'schema-utils';
13 |
14 | import NodeTargetPlugin from 'webpack/lib/node/NodeTargetPlugin';
15 | import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin';
16 |
17 | import getWorker from './worklets/';
18 | import LoaderError from './Error';
19 |
20 | export default function loader() {}
21 |
22 | export function pitch(request) {
23 | const options = loaderUtils.getOptions(this) || {};
24 |
25 | validateOptions(schema, options, 'Worklet Loader');
26 |
27 | if (!this.webpack) {
28 | throw new LoaderError({
29 | name: 'Worklet Loader',
30 | message: 'This loader is only usable with webpack'
31 | });
32 | }
33 |
34 | this.cacheable(false);
35 |
36 | const cb = this.async();
37 |
38 | const filename = loaderUtils.interpolateName(this, options.name || '[hash].worklet.js', {
39 | context: options.context || this.rootContext || this.options.context,
40 | regExp: options.regExp,
41 | });
42 |
43 | const worker = {};
44 |
45 | worker.options = {
46 | filename,
47 | chunkFilename: `[id].${filename}`,
48 | namedChunkFilename: null,
49 | };
50 |
51 | worker.compiler = this._compilation
52 | .createChildCompiler('worker', worker.options);
53 |
54 | // Tapable.apply is deprecated in tapable@1.0.0-x.
55 | // The plugins should now call apply themselves.
56 | // new WebWorkerTemplatePlugin(worker.options).apply(worker.compiler);
57 |
58 | if (this.target !== 'webworker' && this.target !== 'web') {
59 | new NodeTargetPlugin().apply(worker.compiler);
60 | }
61 |
62 | new SingleEntryPlugin(this.context, `!!${request}`, 'main').apply(worker.compiler);
63 |
64 | const subCache = `subcache ${__dirname} ${request}`;
65 |
66 | worker.compilation = (compilation) => {
67 | if (compilation.cache) {
68 | if (!compilation.cache[subCache]) {
69 | compilation.cache[subCache] = {};
70 | }
71 |
72 | compilation.cache = compilation.cache[subCache];
73 | }
74 | };
75 |
76 | if (worker.compiler.hooks) {
77 | const plugin = { name: 'WorkletLoader' };
78 |
79 | worker.compiler.hooks.compilation.tap(plugin, worker.compilation);
80 | } else {
81 | worker.compiler.plugin('compilation', worker.compilation);
82 | }
83 |
84 | worker.compiler.runAsChild((err, entries, compilation) => {
85 | if (err) return cb(err);
86 |
87 | if (entries[0]) {
88 | worker.file = entries[0].files[0];
89 |
90 | worker.factory = getWorker(
91 | worker.file,
92 | compilation.assets[worker.file].source(),
93 | options
94 | );
95 |
96 | if (options.inline) {
97 | delete this._compilation.assets[worker.file];
98 | }
99 |
100 | return cb(null, `module.exports = ${worker.factory};`);
101 | }
102 |
103 | return cb(null, null);
104 | });
105 | }
106 |
--------------------------------------------------------------------------------
/src/options.json:
--------------------------------------------------------------------------------
1 | {
2 | "type": "object",
3 | "properties": {
4 | "name": {
5 | "type": "string"
6 | },
7 | "inline": {
8 | "type": "boolean"
9 | },
10 | "publicPath": {
11 | "type": "string"
12 | }
13 | },
14 | "additionalProperties": false
15 | }
16 |
--------------------------------------------------------------------------------
/src/worklets/InlineWorklet.js:
--------------------------------------------------------------------------------
1 | // http://stackoverflow.com/questions/10343913/how-to-create-a-web-worker-from-a-string
2 |
3 | var URL = window.URL || window.webkitURL;
4 |
5 | module.exports = function (content) {
6 | try {
7 | var blob;
8 |
9 | try {
10 | // BlobBuilder = Deprecated, but widely implemented
11 | var BlobBuilder = window.BlobBuilder ||
12 | window.WebKitBlobBuilder ||
13 | window.MozBlobBuilder ||
14 | window.MSBlobBuilder;
15 |
16 | blob = new BlobBuilder();
17 |
18 | blob.append(content);
19 |
20 | blob = blob.getBlob('application/javascript; charset=utf-8');
21 | } catch (e) {
22 | // The proposed API
23 | blob = new Blob([content], { type: 'application/javascript; charset=utf-8' });
24 | }
25 |
26 | return URL.createObjectURL(blob);
27 | } catch (e) {
28 | return 'data:application/javascript,' + encodeURIComponent(content);
29 | }
30 | };
31 |
--------------------------------------------------------------------------------
/src/worklets/index.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable multiline-ternary */
2 | import path from 'path';
3 |
4 | const getWorklet = (file, content, options) => {
5 | const publicPath = options.publicPath
6 | ? JSON.stringify(options.publicPath)
7 | : '__webpack_public_path__';
8 |
9 | const publicWorkletPath = `${publicPath} + ${JSON.stringify(file)}`;
10 |
11 | if (options.inline) {
12 | const InlineWorkletPath = JSON.stringify(`!!${
13 | path.join(__dirname, 'InlineWorklet.js')
14 | }`);
15 |
16 | return `require(${InlineWorkletPath})(${JSON.stringify(content)})`;
17 | }
18 |
19 | return publicWorkletPath;
20 | };
21 |
22 | export default getWorklet;
23 |
--------------------------------------------------------------------------------
/test/Errors.test.js:
--------------------------------------------------------------------------------
1 | import { pitch } from '../src';
2 |
3 | describe('Errors', () => {
4 | test('Loader Error', () => {
5 | const error = () => pitch.call({ webpack: false, query: {} });
6 |
7 | expect(error).toThrow();
8 | expect(error).toThrowErrorMatchingSnapshot();
9 | });
10 |
11 | test('Validation Error', () => {
12 | const error = () => pitch.call({ query: { name: 1 } });
13 |
14 | expect(error).toThrow();
15 | expect(error).toThrowErrorMatchingSnapshot();
16 | });
17 | });
18 |
--------------------------------------------------------------------------------
/test/__snapshots__/Errors.test.js.snap:
--------------------------------------------------------------------------------
1 | // Jest Snapshot v1, https://goo.gl/fbAQLP
2 |
3 | exports[`Errors Loader Error 1`] = `
4 | "Worklet Loader
5 |
6 | This loader is only usable with webpack
7 | "
8 | `;
9 |
10 | exports[`Errors Validation Error 1`] = `
11 | "Worklet Loader Invalid Options
12 |
13 | options.name should be string
14 | "
15 | `;
16 |
--------------------------------------------------------------------------------
/test/fixtures/inline-fallbacks/entry.js:
--------------------------------------------------------------------------------
1 | const w1 = require('./w1.js');
2 | const w2 = require('./w2.js');
--------------------------------------------------------------------------------
/test/fixtures/inline-fallbacks/w1.js:
--------------------------------------------------------------------------------
1 | // w1 inlined with fallback
--------------------------------------------------------------------------------
/test/fixtures/inline-fallbacks/w2.js:
--------------------------------------------------------------------------------
1 | // w2 inlined with fallback
--------------------------------------------------------------------------------
/test/fixtures/inline-options/entry.js:
--------------------------------------------------------------------------------
1 | const w1 = require('./w1.js');
2 | const w2 = require('./w2.js');
--------------------------------------------------------------------------------
/test/fixtures/inline-options/w1.js:
--------------------------------------------------------------------------------
1 | // w1 inlined via options
--------------------------------------------------------------------------------
/test/fixtures/inline-options/w2.js:
--------------------------------------------------------------------------------
1 | // w2 inlined via options
--------------------------------------------------------------------------------
/test/fixtures/inline-query/entry.js:
--------------------------------------------------------------------------------
1 | const Worker = require('!../../../src?inline!./worker.js');
2 |
--------------------------------------------------------------------------------
/test/fixtures/inline-query/worker.js:
--------------------------------------------------------------------------------
1 | // inlined worker test mark
2 |
--------------------------------------------------------------------------------
/test/fixtures/name-options/entry.js:
--------------------------------------------------------------------------------
1 | const w1 = require('./w1.js');
2 | const w2 = require('./w2.js');
3 |
--------------------------------------------------------------------------------
/test/fixtures/name-options/w1.js:
--------------------------------------------------------------------------------
1 | // w1 via worker options
--------------------------------------------------------------------------------
/test/fixtures/name-options/w2.js:
--------------------------------------------------------------------------------
1 | // w2 via worker options
--------------------------------------------------------------------------------
/test/fixtures/name-query/entry.js:
--------------------------------------------------------------------------------
1 | const Worker = require('!../../../src?name=namedWorker.js!./worker.js');
2 |
--------------------------------------------------------------------------------
/test/fixtures/name-query/worker.js:
--------------------------------------------------------------------------------
1 | // named worker test mark
2 |
--------------------------------------------------------------------------------
/test/fixtures/no-fallbacks/entry.js:
--------------------------------------------------------------------------------
1 | const w1 = require('./w1.js');
2 | const w2 = require('./w2.js');
--------------------------------------------------------------------------------
/test/fixtures/no-fallbacks/w1.js:
--------------------------------------------------------------------------------
1 | // w1 inlined without fallback
--------------------------------------------------------------------------------
/test/fixtures/no-fallbacks/w2.js:
--------------------------------------------------------------------------------
1 | // w2 inlined without fallback
--------------------------------------------------------------------------------
/test/fixtures/nodejs-core-modules/entry.js:
--------------------------------------------------------------------------------
1 | const Worker = require('./worker.js');
2 |
--------------------------------------------------------------------------------
/test/fixtures/nodejs-core-modules/worker.js:
--------------------------------------------------------------------------------
1 | const fs = require('fs');
2 |
--------------------------------------------------------------------------------
/test/fixtures/public-path-override/entry.js:
--------------------------------------------------------------------------------
1 | const Worker = require('./worker.js');
2 |
--------------------------------------------------------------------------------
/test/fixtures/public-path-override/worker.js:
--------------------------------------------------------------------------------
1 | // named worker test mark
2 |
--------------------------------------------------------------------------------
/test/fixtures/worker/entry.js:
--------------------------------------------------------------------------------
1 | const Worker = require('./worker.js');
2 |
--------------------------------------------------------------------------------
/test/fixtures/worker/worker.js:
--------------------------------------------------------------------------------
1 | // worker test mark
2 |
--------------------------------------------------------------------------------
/test/helpers/compiler.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable
2 | import/order,
3 | comma-dangle,
4 | arrow-parens,
5 | multiline-ternary,
6 | no-param-reassign
7 | */
8 | import del from 'del';
9 | import path from 'path';
10 | import webpack from 'webpack';
11 |
12 | export default function (name, config = {}) {
13 | return del(path.resolve(__dirname, `../__expected__/${name}`)).then(() => {
14 | config = {
15 | target: config.target || 'web',
16 | context: path.resolve(__dirname, '../fixtures'),
17 | entry: `./${name}/entry.js`,
18 | output: {
19 | path: path.resolve(__dirname, `../__expected__/${name}`),
20 | filename: 'bundle.js',
21 | },
22 | module: {
23 | rules: [
24 | {
25 | test: config.loader ? config.loader.test : /worker\.js$/,
26 | use: {
27 | loader: '../../src',
28 | options: config.loader ? config.loader.options : {}
29 | }
30 | }
31 | ]
32 | }
33 | };
34 |
35 | const compiler = webpack(config);
36 |
37 | return new Promise((resolve, reject) => {
38 | compiler.run((err, stats) => {
39 | if (err) reject(err);
40 |
41 | resolve(stats);
42 | });
43 | });
44 | });
45 | }
46 |
--------------------------------------------------------------------------------
/test/loader.test.js:
--------------------------------------------------------------------------------
1 | /* eslint-disable
2 | import/order,
3 | comma-dangle,
4 | arrow-parens,
5 | linebreak-style,
6 | prefer-destructuring,
7 | no-underscore-dangle,
8 | array-bracket-spacing,
9 | */
10 | import fs from 'fs';
11 | import assert from 'assert';
12 | import webpack from './helpers/compiler';
13 |
14 | process.chdir(__dirname);
15 |
16 | const readFile = file => fs.readFileSync(file, 'utf-8');
17 |
18 | test('should create chunk with worker', () =>
19 | webpack('worker').then((stats) => {
20 | const files = stats.toJson().children
21 | .map(item => item.chunks)
22 | .reduce((acc, item) => acc.concat(item), [])
23 | .map(item => item.files)
24 | .map(item => `__expected__/worker/${item}`);
25 |
26 | assert.equal(files.length, 1);
27 |
28 | assert.notEqual(readFile(files[0]).indexOf('// worker test mark'), -1);
29 | })
30 | );
31 |
32 | test('should create chunk with specified name in query', () =>
33 | webpack('name-query').then((stats) => {
34 | const files = stats.toJson().children
35 | .map(item => item.chunks)
36 | .reduce((acc, item) => acc.concat(item), [])
37 | .map(item => item.files)
38 | .map(item => `__expected__/name-query/${item}`);
39 |
40 | assert.equal(files[0], '__expected__/name-query/namedWorker.js');
41 |
42 | assert.notEqual(readFile(files[0]).indexOf('// named worker test mark'), -1);
43 | })
44 | );
45 |
46 | test('should create named chunks with workers via options', () =>
47 | webpack('name-options', {
48 | loader: {
49 | test: /(w1|w2)\.js$/,
50 | options: {
51 | name: '[name].js',
52 | },
53 | }
54 | }).then((stats) => {
55 | const files = stats.toJson().children
56 | .map(item => item.chunks)
57 | .reduce((acc, item) => acc.concat(item), [])
58 | .map(item => item.files)
59 | .map(item => `__expected__/name-options/${item}`)
60 | .sort();
61 |
62 | assert.equal(files.length, 2);
63 | assert.equal(files[0], '__expected__/name-options/w1.js');
64 | assert.equal(files[1], '__expected__/name-options/w2.js');
65 |
66 | assert.notEqual(readFile(files[0]).indexOf('// w1 via worker options'), -1);
67 | assert.notEqual(readFile(files[1]).indexOf('// w2 via worker options'), -1);
68 | })
69 | );
70 |
71 | test('should inline worker with inline option in query', () =>
72 | webpack('inline-query').then((stats) => {
73 | const files = stats.toJson().chunks
74 | .map(item => item.files)
75 | .reduce((acc, item) => acc.concat(item), [])
76 | .map(item => `__expected__/inline-query/${item}`);
77 |
78 | assert.equal(files.length, 1);
79 |
80 | assert.notEqual(readFile(files[0]).indexOf('// inlined worker test mark'), -1);
81 | })
82 | );
83 |
84 | test('should inline worker with inline in options', () =>
85 | webpack('inline-options', {
86 | loader: {
87 | test: /(w1|w2)\.js$/,
88 | options: {
89 | inline: true,
90 | },
91 | }
92 | }).then((stats) => {
93 | const files = stats.toJson().chunks
94 | .map(item => item.files)
95 | .reduce((acc, item) => acc.concat(item), [])
96 | .map(item => `__expected__/inline-options/${item}`);
97 |
98 | assert.equal(files.length, 1);
99 |
100 | assert.notEqual(readFile(files[0]).indexOf('// w1 inlined via options'), -1);
101 | assert.notEqual(readFile(files[0]).indexOf('// w2 inlined via options'), -1);
102 | })
103 | );
104 |
105 | test('should not add fallback chunks with inline', () =>
106 | webpack('no-fallbacks', {
107 | loader: {
108 | test: /(w1|w2)\.js$/,
109 | options: {
110 | inline: true,
111 | }
112 | }
113 | }).then((stats) => {
114 | const [ file ] = stats.toJson().chunks
115 | .map(item => item.files)
116 | .reduce((acc, item) => acc.concat(item), [])
117 | .map(item => `__expected__/no-fallbacks/${item}`);
118 |
119 | assert(file);
120 |
121 | assert.equal(fs.readdirSync('__expected__/no-fallbacks').length, 1);
122 |
123 | assert.notEqual(readFile(file).indexOf('// w1 inlined without fallback'), -1);
124 | assert.notEqual(readFile(file).indexOf('// w2 inlined without fallback'), -1);
125 | })
126 | );
127 |
128 | test('should use the publicPath option as the base URL if specified', () =>
129 | webpack('public-path-override', {
130 | loader: {
131 | options: {
132 | publicPath: '/some/proxy/',
133 | }
134 | }
135 | }).then((stats) => {
136 | const assets = stats.compilation.assets;
137 |
138 | const bundle = assets['bundle.js'];
139 | const worker = Object.keys(assets)[1];
140 |
141 | expect(bundle.source()).toContain(`"/some/proxy/" + "${worker}"`);
142 | })
143 | );
144 |
--------------------------------------------------------------------------------