1 | 'use strict'
|
2 |
|
3 | const fs = require('fs')
|
4 | const devalue = require('devalue')
|
5 | const chalk = require('chalk')
|
6 | const ConcatSource = require('webpack-sources/lib/ConcatSource')
|
7 | const { rootPath } = require('../../libs/utils')
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 | class SinaHybridPlugin {
|
14 | constructor(options) {
|
15 | this.options = options
|
16 | this.version = process.env.npm_package_version
|
17 | this.rewriteField = genRewriteFn([
|
18 | rootPath('public/manifest.json'),
|
19 | rootPath(`src/view/${this.options.entry}/public/manifest.json`)
|
20 | ])
|
21 | const pkgVersion = require(rootPath('package.json')).version
|
22 |
|
23 | if (pkgVersion !== this.version) {
|
24 | throw new Error(
|
25 | chalk.red(
|
26 | `package.json 版本号不合法,期望值:${chalk.yellow(this.version)}`
|
27 | )
|
28 | )
|
29 | }
|
30 | }
|
31 |
|
32 | apply(compiler) {
|
33 |
|
34 |
|
35 | compiler.plugin('compilation', compilation => {
|
36 | const maraCtx = compiler['maraContext'] || {}
|
37 |
|
38 | this.genVersionFile(compilation)
|
39 | this.updateManifestVersion()
|
40 | this.injectDataSource(compilation, maraCtx.dataSource)
|
41 |
|
42 |
|
43 | })
|
44 | }
|
45 |
|
46 | genVersionFile(compilation) {
|
47 | compilation.assets[this.version] = {
|
48 |
|
49 | source: () => '',
|
50 | size: () => 0
|
51 | }
|
52 | }
|
53 |
|
54 | updateManifestVersion() {
|
55 | this.rewriteField('version', this.version)
|
56 | }
|
57 |
|
58 | injectDataSource(compilation, dataSource) {
|
59 | var da = { a: 222, b: [{ aaa: 22 }] }
|
60 | if (!dataSource) return
|
61 |
|
62 | this.prependEntryCode(
|
63 | compilation,
|
64 | `var __SP_DATA_SOURCE = ${devalue(dataSource)};`
|
65 | )
|
66 | this.rewriteField('dataSource', dataSource)
|
67 | }
|
68 |
|
69 | prependEntryCode(compilation, code) {
|
70 | const assets = compilation.assets
|
71 | const concatSource = (assets, fileName, code) => {
|
72 | assets[fileName] = new ConcatSource(code, assets[fileName])
|
73 | }
|
74 |
|
75 | compilation.plugin('optimize-chunk-assets', (chunks, callback) => {
|
76 | chunks.forEach(chunk => {
|
77 | if (!chunk.isInitial() || !chunk.name) return
|
78 |
|
79 | chunk.files
|
80 | .filter(fileName => fileName.match(/\.js$/))
|
81 | .forEach(fileName => {
|
82 | concatSource(assets, fileName, code)
|
83 | })
|
84 | })
|
85 |
|
86 | callback()
|
87 | })
|
88 | }
|
89 | }
|
90 |
|
91 | function genRewriteFn(manPath) {
|
92 | return function(field, value) {
|
93 | ;[].concat(manPath).forEach(path => {
|
94 | try {
|
95 | const manifest = require(path)
|
96 |
|
97 |
|
98 |
|
99 | manifest[field] = value
|
100 | fs.writeFileSync(path, JSON.stringify(manifest, null, 2))
|
101 | } catch (e) {}
|
102 | })
|
103 | }
|
104 | }
|
105 |
|
106 |
|
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 |
|
114 |
|
115 |
|
116 |
|
117 |
|
118 |
|
119 | module.exports = SinaHybridPlugin
|