Skip to content
This repository was archived by the owner on Aug 23, 2023. It is now read-only.

Commit 3eb9a34

Browse files
authored
feat: Refactor & Enhance supporting vConsole
BREAKING CHANGE: Change the way to import library and replacement url hash key
1 parent befda4d commit 3eb9a34

File tree

36 files changed

+625
-287
lines changed

36 files changed

+625
-287
lines changed

README.md

+5-5
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
Module to enhance ability of source replacement for website
99

10+
Note: Not using this in production environment
11+
1012
## Installation
1113

1214
```
@@ -15,16 +17,14 @@ yarn add source-replacement
1517

1618
### Usage
1719

18-
#### In your source
20+
Attach `source-replacement/build/executors/source-replacement` on the script tag in `<head>` or mark it as `async type=module`
1921

20-
```
21-
import 'source-replacement'
22-
```
22+
In your source import `source-replacement/build/executors/code-blocker` to prevent executing your source during the process of replacement
2323

2424
#### On your browser
2525

2626
Enter page with the following example
2727

2828
```
29-
https://example.com/#replacementTarget=https://your-target-js-source-url
29+
https://example.com/#targetReplacementSource=https://your-target-js-source-url
3030
```

package.json

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
{
22
"name": "source-replacement",
3-
"version": "0.0.0",
4-
"main": "build/index.js",
5-
"entry": "src/index.ts",
3+
"version": "2.0.0",
64
"types": "build",
75
"deploy": "build",
6+
"main": "build/index.js",
87
"repository": {
98
"type": "git",
109
"url": "https://github.com/wongnai/source-replacement.git"
@@ -40,6 +39,7 @@
4039
"semantic-release": "18.0.0",
4140
"shake-detector": "0.3.7",
4241
"ts-jest": "27.0.7",
43-
"typescript": "4.4.4"
42+
"typescript": "4.4.4",
43+
"vconsole": "3.14.3"
4444
}
4545
}

rollup.config.js

+37-26
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,45 @@
11
import path from 'path'
22

3-
import commonjs from '@rollup/plugin-commonjs';
3+
import commonjs from '@rollup/plugin-commonjs'
44
import json from '@rollup/plugin-json'
5-
import resolve from '@rollup/plugin-node-resolve';
5+
import resolve from '@rollup/plugin-node-resolve'
66
import typescript from '@rollup/plugin-typescript'
77
import visualizer from 'rollup-plugin-visualizer'
88

99
import config from './package.json'
1010

11-
export default {
12-
input: config.entry,
13-
output: {
14-
dir: config.deploy,
15-
format: 'umd',
16-
sourcemap: true,
17-
name: 'SourceReplacement'
18-
},
19-
plugins: [
20-
resolve({
21-
browser: true,
22-
}),
23-
commonjs(),
24-
typescript({
25-
declaration: true,
26-
declarationDir: config.deploy,
27-
exclude: 'src/**/*.test.ts',
28-
}),
29-
json(),
30-
visualizer({
31-
filename: path.resolve(config.deploy, 'stat.html')
32-
}),
33-
],
34-
};
11+
const sharedPlugins = [
12+
resolve({
13+
browser: true,
14+
}),
15+
commonjs(),
16+
typescript({
17+
declaration: true,
18+
declarationDir: config.deploy,
19+
exclude: 'src/**/*.test.ts',
20+
}),
21+
json(),
22+
visualizer({
23+
filename: path.resolve(config.deploy, 'stat.html'),
24+
}),
25+
]
26+
27+
export default [
28+
{
29+
input: 'src/executors/code-blocker/index.ts',
30+
output: {
31+
dir: config.deploy,
32+
format: 'cjs',
33+
},
34+
plugins: sharedPlugins
35+
},
36+
{
37+
input: 'src/executors/source-replacement/index.ts',
38+
output: {
39+
dir: config.deploy,
40+
format: 'umd',
41+
name: 'SourceReplacement',
42+
},
43+
plugins: sharedPlugins,
44+
},
45+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { REPLACEMENT_SOURCE_KEY } from 'debugConstants'
2+
import preventPerformExistingScriptDuringInjection from '.'
3+
4+
describe('preventPerformExistingScriptDuringInjection()', () => {
5+
const MOCK_URL = 'http://example.com'
6+
7+
const promptSpy = jest.spyOn(global, 'prompt').mockReturnValue(MOCK_URL)
8+
9+
Object.defineProperty(window, 'location', {
10+
value: {
11+
reload: jest.fn(),
12+
},
13+
})
14+
15+
class VConsolePlugin {
16+
events: Record<string, any> = {}
17+
18+
on = jest.fn().mockImplementation((key: string, handler: Function) => {
19+
const watcher = jest.fn()
20+
21+
handler(watcher)
22+
23+
this.events[key] = watcher.mock.calls[0][0]
24+
})
25+
}
26+
27+
class FakeVConsole {
28+
static VConsolePlugin = VConsolePlugin
29+
30+
plugins: VConsolePlugin[] = []
31+
32+
addPlugin = jest.fn().mockImplementation(plugin => {
33+
this.plugins.push(plugin)
34+
})
35+
}
36+
37+
window['VConsole'] = FakeVConsole
38+
39+
window['vConsole'] = new FakeVConsole()
40+
41+
afterEach(() => {
42+
jest.clearAllMocks()
43+
sessionStorage.clear()
44+
})
45+
46+
it('should throw exception if app is marked from session that to be replaced', () => {
47+
sessionStorage.setItem(REPLACEMENT_SOURCE_KEY, MOCK_URL)
48+
49+
expect(() => preventPerformExistingScriptDuringInjection()).toThrowError(
50+
new Error(
51+
'The under of code block stop performing causing by replacement process is running',
52+
),
53+
)
54+
})
55+
56+
it('should init vconsole plugin for set source from prompt to session', () => {
57+
preventPerformExistingScriptDuringInjection()
58+
59+
const plugin = window['vConsole'].plugins[0]
60+
61+
expect(window['vConsole'].addPlugin).toBeCalledTimes(1)
62+
expect(window['vConsole'].addPlugin).toBeCalledWith(plugin)
63+
expect(plugin).toBeInstanceOf(VConsolePlugin)
64+
65+
expect(plugin.events.renderTab).toBe('<div>Click to Replacement button below</div>')
66+
67+
expect(plugin.events.addTool).toHaveLength(1)
68+
69+
const addToolEvent = plugin.events.addTool[0]
70+
71+
expect(addToolEvent.name).toBe('Replacement')
72+
73+
addToolEvent.onClick()
74+
75+
expect(promptSpy).toBeCalledTimes(1)
76+
expect(promptSpy).toBeCalledWith('Input target replacement')
77+
78+
expect(sessionStorage.getItem(REPLACEMENT_SOURCE_KEY)).toBe(MOCK_URL)
79+
expect(location.reload).toBeCalledTimes(1)
80+
})
81+
})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { REPLACEMENT_SOURCE_KEY } from 'debugConstants'
2+
3+
import VConsole from 'vconsole'
4+
5+
const PLUGIN_NAME = 'source_replacement'
6+
7+
const TAB_NAME = 'Source Replacement'
8+
9+
function preventPerformExistingScriptDuringInjection() {
10+
if (sessionStorage.getItem(REPLACEMENT_SOURCE_KEY)) {
11+
throw new Error(
12+
'The under of code block stop performing causing by replacement process is running',
13+
)
14+
} else {
15+
const Console: typeof VConsole = window['VConsole']
16+
17+
const consoleInstance: VConsole = window['vConsole']
18+
19+
if (Console && consoleInstance) {
20+
const plugin = new Console.VConsolePlugin(PLUGIN_NAME, TAB_NAME)
21+
22+
plugin.on('renderTab', callback => {
23+
callback('<div>Click to Replacement button below</div>')
24+
})
25+
26+
plugin.on('addTool', callback => {
27+
callback([
28+
{
29+
name: 'Replacement',
30+
onClick: () => {
31+
const targetSource = prompt('Input target replacement')
32+
33+
sessionStorage.setItem(REPLACEMENT_SOURCE_KEY, targetSource!)
34+
35+
location.reload()
36+
},
37+
},
38+
])
39+
})
40+
41+
consoleInstance.addPlugin(plugin)
42+
}
43+
}
44+
}
45+
46+
export default preventPerformExistingScriptDuringInjection

src/core/replaceSourceWithTargetSource/index.test.ts

-32
This file was deleted.

src/core/replaceSourceWithTargetSource/index.ts

-21
This file was deleted.

src/core/startDevTool/index.test.ts

-44
This file was deleted.

src/core/startDevTool/index.ts

-22
This file was deleted.

0 commit comments

Comments
 (0)