├── .eslintrc.js ├── .gitignore ├── .npmignore ├── LICENSE ├── README.md ├── generator.js ├── logo.png ├── package.json ├── service.js └── src ├── dll.js ├── fileNameCachePlugin.js └── helper.js /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 'root': true, 3 | 'env': { 4 | 'node': true 5 | }, 6 | 'extends': [ 7 | 'standard' 8 | ], 9 | rules: { 10 | 'indent': 0, 11 | 'no-tabs': 0, 12 | 'space-before-function-paren': 0 13 | }, 14 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Dependency directories 4 | node_modules 5 | 6 | # npm 7 | npm-debug.log 8 | package-lock.json 9 | .npm 10 | .history 11 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | # Dependency directories 2 | node_modules 3 | 4 | # npm 5 | npm-debug.log 6 | package-lock.json 7 | .npm 8 | 9 | # 10 | .eslintrc.js -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 youngpan 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # vue-cli-plugin-dll [![vue-cli3](https://img.shields.io/badge/vue--cli-3.x-brightgreen.svg)](https://github.com/vuejs/vue-cli) ![npm](https://img.shields.io/npm/dm/vue-cli-plugin-dll.svg) [![npm](https://img.shields.io/npm/v/vue-cli-plugin-dll.svg)](https://www.npmjs.com/package/vue-cli-plugin-dll) 3 | 4 | This is a vue-cli 3.x plugin for webpack [Dll-Plugin](https://webpack.js.org/plugins/dll-plugin/) that can drastically improve build time performance. `vue-cli-plugin-dll` plugin register `dll` instruction to avoid adding extra webpack config file, it also insert DllReferencePlugin and inject chunk files automatically when you run `dev/build` directives. 5 | 6 | 7 | ### English | [中文](https://github.com/fingerpan/vue-cli-plugin-dll/wiki/zh_cn.md) 8 | ## Quick Start 9 | 10 | > Make sure you have the vue-cli 3.x.x version installed 11 | 12 | ``` bash 13 | $ vue -V 14 | ``` 15 | 16 | ### Install plugin 17 | ``` bash 18 | $ vue add dll 19 | 20 | # OR 21 | 22 | $vue invoke dll 23 | ``` 24 | 25 | ### Simple configuration 26 | ```javascript 27 | // vue.config.js 28 | 29 | module.exports = { 30 | pluginOptions: { 31 | dll: { 32 | entry: ['vue', 'vue-router'], 33 | cacheFilePath: path.resolve(__dirname, './public') 34 | } 35 | } 36 | } 37 | ``` 38 | ### Execution 39 | ```bash 40 | $ npm run dll 41 | 42 | #OR 43 | 44 | $ npx vue-cli-service dll 45 | ``` 46 | 47 | 48 | ## Configuration 49 | 50 | ### Options 51 | 52 | | Parame | Type | Description| Default | Required | 53 | | :--- | :--- | :--- | :--- | :--- | 54 | | entry | Object/Array/String | entry vendor | null | true 55 | | open | Boolean | whether to add DllReferencePlugin plugin | true | false 56 | | output | Object | output | | false 57 | | output.path | String | The output directory as an absolute path | 'yourProjectPath/public/dll' | false 58 | | output.publicPath | Srting | publicPath | '' | false 59 | | inject | Boolean | auto inject file to index.html | true | false 60 | | cacheFilePath | String | The path that save vender path| 'yourProjectPath/node_modules/vue-cli-plugin-dll/src' | false 61 | 62 | ### vue.config.js 63 | ``` javascript 64 | module.exports = { 65 | // Other options... 66 | 67 | pluginOptions: { 68 | dll: { 69 | entry: ['vue'], 70 | 71 | /** 72 | * the directory path where the vendor files will be generated in 73 | * when running vue-cli-service dll 74 | */ 75 | output: path.join(__dirname, './public/dll'), 76 | 77 | // If you only want to open `dll plugin` during production build, 78 | // you can use the following config: 79 | open: process.env.NODE_ENV === 'production', 80 | 81 | // !! Recommended configuration 82 | cacheFilePath: path.resolve(__dirname, './public') 83 | } 84 | } 85 | } 86 | ``` 87 | 88 | ## License 89 | MIT 90 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /generator.js: -------------------------------------------------------------------------------- 1 | module.exports = (api) => { 2 | api.extendPackage({ 3 | scripts: { 4 | 'dll': 'vue-cli-service dll' 5 | } 6 | }) 7 | } 8 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/fingerpan/vue-cli-plugin-dll/d8010ab7f5b2fabb348aaaff377c5909b4c688db/logo.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "vue-cli-plugin-dll", 3 | "version": "1.1.12", 4 | "description": "vue-cli 3 plugin for Dll and DllReference", 5 | "main": "service.js", 6 | "repository": "git+https://github.com/fingerpan/vue-cli-plugin-dll.git", 7 | "homepage": "https://github.com/fingerpan/vue-cli-plugin-dll", 8 | "keywords": [ 9 | "vue", 10 | "vue-cli", 11 | "plugin", 12 | "Dll", 13 | "DllReference" 14 | ], 15 | "author": "youngpan", 16 | "license": "MIT", 17 | "engines": { 18 | "node": ">=8.0" 19 | }, 20 | "dependencies": { 21 | "add-asset-html-webpack-plugin": "^3.1.2", 22 | "friendly-errors-webpack-plugin": "^1.7.0", 23 | "mini-css-extract-plugin": "^0.5.0", 24 | "vue-loader": "^15.7.0", 25 | "@intervolga/optimize-cssnano-plugin": "^1.0.6" 26 | }, 27 | "peerDependencies": { 28 | "@vue/cli-service": "^3.3.0" 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /service.js: -------------------------------------------------------------------------------- 1 | const { 2 | log, 3 | isInstallOf, 4 | forEachObj, 5 | isFunctionAndCall 6 | } = require('./src/helper') 7 | 8 | const Dll = require('./src/dll.js') 9 | 10 | module.exports = (api, options) => { 11 | const webpack = require('webpack') 12 | const dllConfig = (options.pluginOptions && options.pluginOptions.dll) || {} 13 | const dll = new Dll(api.resolveWebpackConfig(), dllConfig) 14 | 15 | api.chainWebpack(config => { 16 | if (!dll.isOpen || dll.isCommand === true) return 17 | 18 | const referenceArgs = dll.resolveDllReferenceArgs() 19 | 20 | config.when(referenceArgs.length !== 0, config => { 21 | // add DllReferencePlugins 22 | referenceArgs.forEach(args => { 23 | config 24 | .plugin(`dll-reference-${args.manifest.name}`) 25 | .use(webpack.DllReferencePlugin, [args]) 26 | }) 27 | 28 | // auto inject 29 | if (dll.inject) { 30 | config 31 | .plugin('dll-add-asset-html') 32 | .use( 33 | require('add-asset-html-webpack-plugin'), 34 | dll.resolveAddAssetHtmlArgs() 35 | ) 36 | if(config.plugins.has('copy')) { 37 | // add copy agrs 38 | config.plugin('copy').tap(args => { 39 | args[0][0].ignore.push(dll.outputDir + '/**') 40 | args[0].push({ 41 | from: dll.outputPath, 42 | toType: 'dir', 43 | ignore: ['*.js', '*.css', '*.manifest.json'] 44 | }) 45 | return args 46 | }) 47 | } 48 | } 49 | }) 50 | }) 51 | 52 | api.registerCommand( 53 | 'dll', 54 | { 55 | description: 'build dll', 56 | usage: 'vue-cli-service dll', 57 | options: {} 58 | }, 59 | async function(args) { 60 | dll.callCommand() 61 | 62 | // entry parameter can not be empty 63 | if (!dll.validateEntry()) { 64 | throw Error('"entry" parameter no found, more config url:') 65 | } 66 | 67 | const FileNameCachePlugin = require('./src/fileNameCachePlugin') 68 | 69 | api.chainWebpack(config => { 70 | config 71 | .plugin('dll') 72 | .use(webpack.DllPlugin, dll.resolveDllArgs()) 73 | .end() 74 | .plugin('file-list-plugin') 75 | .use(FileNameCachePlugin) 76 | 77 | config.optimization.delete('splitChunks') 78 | config.optimization.delete('runtimeChunk') 79 | config.devtool(false) 80 | 81 | // set output 82 | forEachObj(dll.resolveOutput(), (fnName, value) => { 83 | isFunctionAndCall( 84 | config.output[fnName], 85 | config.output, 86 | value 87 | ) 88 | }) 89 | }) 90 | 91 | let webpackConfig = api.resolveWebpackConfig() 92 | let { VueLoaderPlugin } = require('vue-loader') 93 | let DefinePlugin = require('webpack/lib/DefinePlugin') 94 | let FriendlyErrorsWebpackPlugin = require('friendly-errors-webpack-plugin') 95 | let NamedChunksPlugin = require('webpack/lib/NamedChunksPlugin') 96 | let MiniCssExtreactPlugin = require('mini-css-extract-plugin') 97 | let OptimizeCssnanoPlugin = require('@intervolga/optimize-cssnano-plugin') 98 | let fs = require('fs-extra') 99 | 100 | // filter plugins 101 | webpackConfig.plugins = webpackConfig.plugins.filter(i => 102 | isInstallOf( 103 | i, 104 | VueLoaderPlugin, 105 | DefinePlugin, 106 | FriendlyErrorsWebpackPlugin, 107 | NamedChunksPlugin, 108 | MiniCssExtreactPlugin, 109 | webpack.DllPlugin, 110 | FileNameCachePlugin, 111 | OptimizeCssnanoPlugin 112 | ) 113 | ) 114 | 115 | // reset entry 116 | webpackConfig.entry = dll.resolveEntry() 117 | 118 | // remove dir 119 | fs.remove(dll.outputPath) 120 | 121 | log('Starting build dll...') 122 | return new Promise((resolve, reject) => { 123 | webpack(webpackConfig, (err, stats) => { 124 | if (err) { 125 | return reject(err) 126 | } else if (stats.hasErrors()) { 127 | return reject(new Error('Build failed with errors.')) 128 | } 129 | 130 | log('Build complete.') 131 | resolve() 132 | }) 133 | }) 134 | } 135 | ) 136 | } 137 | 138 | module.exports.defaultModes = { 139 | dll: 'production' 140 | } 141 | -------------------------------------------------------------------------------- /src/dll.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | const { 3 | isObject, 4 | merge, 5 | normalizeRntry, 6 | tryGetManifestJson, 7 | replaceAsyncName, 8 | getAssetHtmlPluginDefaultArg, 9 | isAcceptTypeByAssetPluginByPath, 10 | compose 11 | } = require('./helper') 12 | const { 13 | getCacheFileNameList, 14 | setCacheFileNamePath 15 | } = require('./fileNameCachePlugin') 16 | 17 | /** 18 | * class Dll 19 | */ 20 | module.exports = class Dll { 21 | /** 22 | * dll default config 23 | */ 24 | static getDllDefaultConfig() { 25 | return { 26 | // 是否开启dll 27 | open: true, 28 | // 自动将vender文件注入 29 | inject: true 30 | } 31 | } 32 | static getDefaultConfig() { 33 | return { 34 | // manifeat file 35 | manifest: '[name].manifest.json', 36 | // output fileName 37 | filename: '[name].[hash:8].dll.js', 38 | // common library name 39 | library: '[name]_library', 40 | // the name of directory specified after output 41 | outputDir: 'dll' 42 | } 43 | } 44 | 45 | constructor(webpackConfig = {}, dllConfig = {}) { 46 | this.webpackConfig = webpackConfig 47 | this.dllConfig = merge(Dll.getDllDefaultConfig(), dllConfig) 48 | this.context = webpackConfig.context 49 | this.isCommand = false 50 | this.isOpen = false 51 | this.inject = this.dllConfig.inject 52 | 53 | // TODO: release more option 54 | merge(this, Dll.getDefaultConfig()) 55 | 56 | // init 57 | this.initEntry() 58 | this.initOutputPath() 59 | this.initOpen() 60 | this.initCatchPath() 61 | } 62 | 63 | // init options ------ 64 | // init entey 65 | initEntry() { 66 | this.entry = normalizeRntry(this.dllConfig.entry) 67 | } 68 | initOutputPath() { 69 | let output = this.dllConfig.output 70 | // normal 71 | if (typeof output === 'string') { 72 | output = { 73 | path: output 74 | } 75 | } 76 | if (output && !isObject(output)) { 77 | output = null 78 | // TODO: 79 | console.warn(`type check failed for output parameter, Expected Object or String`) 80 | } 81 | const DEFAULT_OUTPUT_PATH = path.join( 82 | this.context, 83 | './public', 84 | this.outputDir 85 | ) 86 | this.outputPath = (output && output.path) || DEFAULT_OUTPUT_PATH 87 | } 88 | initOpen() { 89 | let open = this.dllConfig.open 90 | this.isOpen = open == true ? this.validateEntry() : open 91 | } 92 | initCatchPath() { 93 | let cacheFilePath = this.dllConfig.cacheFilePath 94 | if (cacheFilePath) { 95 | setCacheFileNamePath(cacheFilePath) 96 | } 97 | } 98 | 99 | // tool ------------- 100 | /** 101 | * validate has entry 102 | * @return {boolean} 103 | */ 104 | validateEntry() { 105 | return Object.keys(this.entry).length !== 0 106 | } 107 | 108 | /** 109 | * set isCommand if call dll command 110 | */ 111 | callCommand() { 112 | this.isCommand = true 113 | } 114 | 115 | // resolve args --------------- 116 | /** 117 | * the method resolves a sequence of paths into an absolute path which relative to outputPath 118 | * @param {subPath} args A sequence of paths 119 | */ 120 | resolvePathRelativeOutputPath(subPath) { 121 | return path.resolve(this.outputPath, subPath) 122 | } 123 | 124 | /** 125 | * get entry config for webpack 126 | */ 127 | resolveEntry() { 128 | return JSON.parse(JSON.stringify(this.entry)) 129 | } 130 | 131 | /** 132 | * get output config for webpack 133 | */ 134 | resolveOutput() { 135 | return { 136 | path: this.outputPath, 137 | filename: this.filename, 138 | library: this.library 139 | } 140 | } 141 | 142 | /** 143 | * get dll config for webpack.DllPlugin plugin 144 | */ 145 | resolveDllArgs() { 146 | return [{ 147 | path: this.resolvePathRelativeOutputPath(this.manifest), 148 | name: this.library 149 | }] 150 | } 151 | 152 | /** 153 | * get dllReferenceArgs config for webpack.DllReferenceArgs plugin 154 | */ 155 | resolveDllReferenceArgs() { 156 | return Object.keys(this.resolveEntry()) 157 | .map(entryName => { 158 | const jsonPath = this.resolvePathRelativeOutputPath( 159 | this.manifest.replace('[name]', entryName) 160 | ) 161 | return tryGetManifestJson(jsonPath) 162 | }) 163 | .filter(i => !!i) 164 | .map(manifest => { 165 | return { 166 | context: this.context, 167 | manifest 168 | } 169 | }) 170 | } 171 | 172 | /** 173 | * get config args for add-asset-html-webpack-plugin plugin 174 | */ 175 | resolveAddAssetHtmlArgs() { 176 | const dll = this 177 | let resolvePathRelativeOutputPathBind = this.resolvePathRelativeOutputPath.bind( 178 | dll 179 | ) 180 | let sourceList = getCacheFileNameList().map( 181 | resolvePathRelativeOutputPathBind 182 | ) 183 | let assetHtmlPluginArg 184 | 185 | function _getAssetHtmlPluginDefaultArg(filename) { 186 | return getAssetHtmlPluginDefaultArg(filename, dll) 187 | } 188 | 189 | if (sourceList.length > 0) { 190 | assetHtmlPluginArg = sourceList 191 | .filter(isAcceptTypeByAssetPluginByPath) 192 | .map(_getAssetHtmlPluginDefaultArg) 193 | } else { 194 | // TODO: remove next verson 195 | console.warn('您更新最新版本,请您重新构建一下dll文件,执行npm run dll') 196 | assetHtmlPluginArg = compose( 197 | _getAssetHtmlPluginDefaultArg, 198 | resolvePathRelativeOutputPathBind, 199 | replaceAsyncName 200 | )(this.filename) 201 | } 202 | return [assetHtmlPluginArg] 203 | } 204 | } -------------------------------------------------------------------------------- /src/fileNameCachePlugin.js: -------------------------------------------------------------------------------- 1 | const fs = require('fs') 2 | const path = require('path') 3 | 4 | const CATCH_FILE_NAME = 'cache.dll.json' 5 | const DEFAULT_CACHE_File_PATH = path.resolve(__dirname, './', CATCH_FILE_NAME) 6 | const PLUGIN_NAME = 'FileNameCachePlugin' 7 | const noop = () => {} 8 | 9 | function FileNameCachePlugin() {} 10 | 11 | FileNameCachePlugin.cacheFilePath = DEFAULT_CACHE_File_PATH 12 | FileNameCachePlugin.pluginName = PLUGIN_NAME 13 | 14 | FileNameCachePlugin.saveCacheFileNameList = function saveCacheFileNameList( 15 | list 16 | ) { 17 | let cacheFilePath = FileNameCachePlugin.cacheFilePath 18 | fs.writeFile(cacheFilePath, JSON.stringify(list), noop) 19 | } 20 | 21 | FileNameCachePlugin.getCacheFileNameList = function getCacheFileNameList() { 22 | let data = null 23 | try { 24 | data = JSON.parse( 25 | fs.readFileSync(FileNameCachePlugin.cacheFilePath, 'utf8') 26 | ) 27 | } catch (e) { 28 | data = [] 29 | } 30 | return data 31 | } 32 | 33 | FileNameCachePlugin.setCacheFileNamePath = function setCacheFileNamePath( 34 | absolutePath 35 | ) { 36 | let absoluteFilePath = path.resolve(absolutePath, './', CATCH_FILE_NAME) 37 | FileNameCachePlugin.cacheFilePath = absoluteFilePath 38 | } 39 | 40 | FileNameCachePlugin.prototype.apply = function apply(compiler) { 41 | compiler.hooks.emit.tapAsync( 42 | FileNameCachePlugin.pluginName, 43 | (compilation, callback) => { 44 | // save last run dll command output name 45 | FileNameCachePlugin.saveCacheFileNameList( 46 | Object.keys(compilation.assets) 47 | ) 48 | callback() 49 | } 50 | ) 51 | } 52 | 53 | module.exports = FileNameCachePlugin 54 | -------------------------------------------------------------------------------- /src/helper.js: -------------------------------------------------------------------------------- 1 | /** 2 | * is plain object 3 | * @param {any} i validate source 4 | * @return {Boolean} result 5 | */ 6 | const isObject = i => Object.prototype.toString.call(i) === '[object Object]' 7 | 8 | /** 9 | * forEach Object 10 | * @param {Object} obj target Source 11 | * @param {*} callback callback 12 | */ 13 | const forEachObj = (obj, callback) => { 14 | if (!isObject(obj)) return false 15 | for (const key in obj) { 16 | if (obj.hasOwnProperty(key)) callback(key, obj[key]) 17 | } 18 | return obj 19 | } 20 | 21 | /** 22 | * is function to call 23 | * @param {Function} fn target Func 24 | * @param {Object} context fn context 25 | * @param {...any} args fn arguments 26 | * @returns result of function call 27 | */ 28 | const isFunctionAndCall = (fn, context, ...args) => { 29 | return typeof fn === 'function' && fn.apply(context, args) 30 | } 31 | 32 | /** 33 | * extend object 34 | * @param {Object} target target 35 | * @param {...Object} sources sourceList 36 | * @returns {Object} target 37 | */ 38 | const merge = (target, ...sources) => { 39 | sources.forEach(sourceItem => { 40 | if (!isObject(sourceItem)) { 41 | return 42 | } 43 | forEachObj(sourceItem, (key, value) => { 44 | target[key] = value 45 | }) 46 | }) 47 | return target 48 | } 49 | 50 | const log = msg => { 51 | msg && console && console.log && console.log(msg) 52 | } 53 | 54 | const isInstallOf = (target, ...classList) => { 55 | return classList.some(C => target instanceof C || target.constructor === C || target.constructor.name === C.name) 56 | } 57 | 58 | const compose = function compose(...funs) { 59 | let length = funs.length 60 | if (length === 0) { 61 | return i => i 62 | } else if (length === 1) { 63 | return funs[0] 64 | } 65 | return funs.reduce((a, b) => (...args) => a(b(...args))) 66 | } 67 | 68 | // match dll 69 | const MatchEntryNameREG = /^(dll)$|^dll_([a-zA-Z]+)/ 70 | exports.MatchEntryName_REG = MatchEntryNameREG 71 | exports.getEntryByWConfig = entry => { 72 | if (!isObject(entry)) { 73 | return {} 74 | } 75 | let entryKeys = Object.keys(entry) 76 | return entryKeys 77 | .map(i => { 78 | let result = i.match(MatchEntryNameREG) 79 | if (result) { 80 | let { 1: defaultName, 2: entryName } = result 81 | return defaultName || entryName 82 | } 83 | return result 84 | }) 85 | .filter(i => !!i) 86 | .reduce((newEntry, name) => { 87 | let enteryKey = name === 'dll' ? name : `dll_${name}` 88 | newEntry[name] = entry[enteryKey] 89 | return newEntry 90 | }, {}) 91 | } 92 | 93 | exports.normalizeRntry = (entry = {}) => { 94 | if (!isObject(entry) && entry) { 95 | entry = { 96 | dll: entry 97 | } 98 | } 99 | 100 | forEachObj(entry, (name, entryValue) => { 101 | entry[name] = Array.isArray(entryValue) ? entryValue : [entryValue] 102 | }) 103 | return entry 104 | } 105 | 106 | exports.tryGetManifestJson = jsonPath => { 107 | let getJon = null 108 | try { 109 | getJon = require(jsonPath) 110 | } catch (e) { 111 | log(' ') 112 | log('vue-cli-plugin-dll warning!! miss manifest.json') 113 | log(' ') 114 | log(' ') 115 | log(`no found ${jsonPath}`) 116 | log(' ') 117 | log( 118 | `if you want to use DllReferencePlugin,execute the command 'npm run dll' first` 119 | ) 120 | log(' ') 121 | } 122 | return getJon 123 | } 124 | 125 | exports.replaceAsyncName = i => i.replace(/\[.+\]/g, '*') 126 | 127 | /** 128 | * get file type 129 | * @param {String} filePath 130 | */ 131 | const getFileType = filePath => { 132 | return filePath.substring(filePath.lastIndexOf('.') + 1) 133 | } 134 | 135 | const isAcceptTypeByAssetPlugin = typeOfAsset => { 136 | return /js|css/.test(typeOfAsset) 137 | } 138 | 139 | const isAcceptTypeByAssetPluginByPath = compose( 140 | isAcceptTypeByAssetPlugin, 141 | getFileType 142 | ) 143 | 144 | /** 145 | * get default Args for add-asset-html-webpack-plugin plugin 146 | * @param {string} filepath filePath 147 | */ 148 | const getAssetHtmlPluginDefaultArg = (filepath, dll) => { 149 | // 获取格式 150 | let typeOfAsset = getFileType(filepath) 151 | if (!isAcceptTypeByAssetPlugin(typeOfAsset)) { 152 | return false 153 | } 154 | const publicPath = dll.webpackConfig.output.publicPath 155 | return { 156 | filepath, 157 | includeSourcemap: false, 158 | typeOfAsset: typeOfAsset, 159 | publicPath: publicPath + typeOfAsset, 160 | outputPath: typeOfAsset 161 | } 162 | } 163 | 164 | exports.log = log 165 | exports.merge = merge 166 | exports.compose = compose 167 | exports.getFileType = getFileType 168 | exports.isObject = isObject 169 | exports.forEachObj = forEachObj 170 | exports.isInstallOf = isInstallOf 171 | exports.isFunctionAndCall = isFunctionAndCall 172 | exports.getAssetHtmlPluginDefaultArg = getAssetHtmlPluginDefaultArg 173 | exports.isAcceptTypeByAssetPluginByPath = isAcceptTypeByAssetPluginByPath --------------------------------------------------------------------------------