1 | const path = require('path')
|
2 | const fs = require('fs-extra')
|
3 | const VendorExtracter = require('./extracter')
|
4 | const chalk = require('chalk')
|
5 |
|
6 | module.exports = extract
|
7 |
|
8 | function extract (opts) {
|
9 | const entries = Array.isArray(opts.entries) ? opts.entries : []
|
10 | const fileModuleFomatter = opts.fileModuleFomatter || (i => i)
|
11 | const moduleFilter = opts.moduleFilter || (_ => true)
|
12 | const appendVersion = opts.appendVersion
|
13 |
|
14 |
|
15 | const vendorPrefix = opts.prefix || 'gallery/'
|
16 | const vendorFileNameTemplate = opts.fileNameTemplate || 'pkg.[name].js'
|
17 | const loaders = opts.loaders || []
|
18 | const prodMode = opts.prodMode || false
|
19 |
|
20 | const tempDirectory = path.join(process.cwd(), '.vext-tmp')
|
21 | const outputPath = opts.output || tempDirectory
|
22 |
|
23 | try {
|
24 | fs.ensureDirSync(tempDirectory)
|
25 | }
|
26 | catch (e) {
|
27 | console.log(`临时目录创建失败... ${e.message}`)
|
28 | process.exit(1)
|
29 | }
|
30 |
|
31 | console.log('vendor 列表提取开始')
|
32 |
|
33 | const extracter = new VendorExtracter({
|
34 | fileModuleFomatter, moduleFilter
|
35 | })
|
36 | const vendorList = extracter.parse(entries)
|
37 |
|
38 | const vendorMap = vendorList.reduce((ret, vendor) => {
|
39 | try {
|
40 | const main = require.resolve(vendor)
|
41 | ret[vendor] = appendVersion ? resolveNpmVersion(main) : ''
|
42 | }
|
43 | catch (e) {
|
44 | console.log(chalk.red(`[Extracter] 找不到模块 ${vendor}`));
|
45 | }
|
46 |
|
47 | return ret
|
48 | }, {})
|
49 | const vendorEntryContent = extracter.output(Object.keys(vendorMap))
|
50 | const vendorEntryFile = path.join(tempDirectory, 'vendors.js')
|
51 | try {
|
52 | fs.writeFileSync(vendorEntryFile, vendorEntryContent)
|
53 | console.log('vendor 依赖入口已生成完成');
|
54 | }
|
55 | catch (e) {
|
56 | console.log(`写入临时文件失败... ${e.message}`)
|
57 | process.exit(1)
|
58 | }
|
59 |
|
60 | console.log('=======================')
|
61 | console.log('webpack 文件生成开始')
|
62 |
|
63 | const webpack = require('webpack')
|
64 | const FmdTemplatePlugin = require('../webpack-fmd')
|
65 | const webpackConfig = {
|
66 | entry: {
|
67 | vendors: vendorEntryFile
|
68 | },
|
69 | output: {
|
70 | path: outputPath,
|
71 | filename: vendorFileNameTemplate,
|
72 | publicPath: '/static/'
|
73 | },
|
74 | module: {
|
75 | loaders
|
76 | },
|
77 | plugins: [
|
78 | new FmdTemplatePlugin({
|
79 | prefix: vendorPrefix,
|
80 | name: 'vendors',
|
81 | deps: vendorMap
|
82 | })
|
83 | ]
|
84 | }
|
85 | if (prodMode) {
|
86 | webpackConfig.devtool = 'source-map'
|
87 | webpackConfig.plugins.push(
|
88 | new webpack.DefinePlugin({
|
89 | 'process.env.NODE_ENV': JSON.stringify('production')
|
90 | })
|
91 | )
|
92 | }
|
93 | webpack(webpackConfig, (err, stats) => {
|
94 | if (err) {
|
95 | console.log(`webpack 生成文件失败... ${err.message}`)
|
96 | }
|
97 | else {
|
98 | console.log('任务成功')
|
99 | }
|
100 | })
|
101 | }
|
102 |
|
103 | function resolveNpmVersion (main) {
|
104 | try {
|
105 | const pkgFile = resolvePkg(main)
|
106 | if (pkgFile) {
|
107 | const pkg = require(pkgFile)
|
108 | }
|
109 |
|
110 | return pkg.version
|
111 | }
|
112 | catch (e) {
|
113 | console.log(chalk.red(`[Extracter] 找不到模块 ${moduleName}`));
|
114 | }
|
115 | }
|
116 |
|
117 | function resolvePkg (main) {
|
118 | if (path.basename(main) == 'node_modules' || main == '/') return
|
119 |
|
120 | const pkgFile = path.join(main, '../package.json')
|
121 | if (fs.existsSync(pkgFile)) return pkgFile
|
122 | else {
|
123 | return resolvePkg(path.join(main, '..'))
|
124 | }
|
125 | }
|