DllPlugin

2024-06-13 06:12
文章标签 dllplugin

本文主要是介绍DllPlugin,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

什么是DLL

  • DllPluginDllReferencePlugin提供了拆分包的方法,可以极大地提高构建时性能。术语DLL代表动态链接库,它最初是由Microsoft引入的。
  • .dll为后缀的文件称为动态链接库,在一个动态链接库中可以包含给其他模块调用的函数和数据
  • 把基础模块独立出来打包到单独的动态连接库里
  • 当需要导入的模块在动态连接库里的时候,模块不能再次被打包,而是去动态连接库里获取

使用DLL

安装依赖

cnpm i webpack webpack-cli html-webpack-plugin isarray is-promise -D

定义Dll

  • dll-plugin
  • DllPlugin插件: 用于打包出一个个动态连接库
  • DllReferencePlugin: 在配置文件中引入DllPlugin插件打包好的动态连接库

webpack.dll.config.js

const path = require("path");
const DllPlugin = require("webpack/lib/DllPlugin");
const DllPlugin2 = require("./plugins/DllPlugin");
module.exports = {mode: "development",devtool: false,entry: {utils:["isarray","is-promise"]},output: {path: path.resolve(__dirname, "dist"),filename: "utils.dll.js", //react.dll.jslibrary: "_dll_utils",},plugins: [new DllPlugin2({//暴露出去的dll函数name: "_dll_utils",//输出的manifest json文件的绝对路径path: path.join(__dirname, "dist", "utils.manifest.json")}),],
};

使用动态链接库文件

webpack.config.js

const path = require("path");
const DllReferencePlugin = require("webpack/lib/DllReferencePlugin.js");
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {mode: "development",devtool: false,entry: "./src/index.js",output: {path: path.resolve(__dirname, 'dist'),filename: 'bundle.js'},plugins: [new DllReferencePlugin({manifest: require("./dist/utils.manifest.json"),}),new HtmlWebpackPlugin({template: './src/index.html'})],
};

html中使用

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>dll</title>
</head>
<body><div id="root"></div><script src="utils.dll.js"></script>
</body>
</html>

index.js

src\index.js

let isarray = require("isarray");
console.log('isarray([1, 2, 3])=',isarray([1, 2, 3]));

package.json

package.json

  "scripts": {"dll": "webpack --config webpack.dll.config.js","build": "webpack --config webpack.config.js"}

dll.js

const webpack = require("webpack");
const webpackOptions = require("./webpack.dll.config");
const compiler = webpack(webpackOptions);
debugger
compiler.run((err, stats) => {console.log(stats.toJson({}));
});

build.js

const webpack = require("webpack");
const webpackOptions = require("./webpack.config");
const compiler = webpack(webpackOptions);
compiler.run((err, stats) => {console.log(stats.toJson({}));
});

打包文件分析

index.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>dll</title>
</head>
<body><div id="root"></div><script src="utils.dll.js"></script><script src="bundle.js"></script></body>
</html>

utils.dll.js

dist\utils.dll.js

var _dll_utils =(function (modules) {var installedModules = {};function __webpack_require__(moduleId) {if (installedModules[moduleId]) {return installedModules[moduleId].exports;}var module = installedModules[moduleId] = {i: moduleId,l: false,exports: {}};modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);module.l = true;return module.exports;}return __webpack_require__(__webpack_require__.s = 0);})({"./node_modules/_is-promise@4.0.0@is-promise/index.js":(function (module, exports) {module.exports = isPromise;module.exports.default = isPromise;function isPromise(obj) {return !!obj && (typeof obj === 'object' || typeof obj === 'function') && typeof obj.then === 'function';}}),"./node_modules/_isarray@2.0.5@isarray/index.js":(function (module, exports) {var toString = {}.toString;module.exports = Array.isArray || function (arr) {return toString.call(arr) == '[object Array]';};}),0:(function (module, exports, __webpack_require__) {module.exports = __webpack_require__;})});

utils.manifest.json

dist\utils.manifest.json

{"name": "_dll_utils","content": {"./node_modules/_is-promise@4.0.0@is-promise/index.js": {"id": "./node_modules/_is-promise@4.0.0@is-promise/index.js","buildMeta": { "providedExports": true }},"./node_modules/_isarray@2.0.5@isarray/index.js": {"id": "./node_modules/_isarray@2.0.5@isarray/index.js","buildMeta": {"providedExports": true}}}
}

bundle.js

dist\bundle.js

(function (modules) {var installedModules = {};function __webpack_require__(moduleId) {if (installedModules[moduleId]) {return installedModules[moduleId].exports;}var module = installedModules[moduleId] = {i: moduleId,l: false,exports: {}};modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);module.l = true;return module.exports;}return __webpack_require__(__webpack_require__.s = "./src/index.js");
})({"./node_modules/_isarray@2.0.5@isarray/index.js":(function (module, exports, __webpack_require__) {module.exports = (__webpack_require__("dll-reference _dll_utils"))("./node_modules/_isarray@2.0.5@isarray/index.js");}),"./src/index.js":(function (module, exports, __webpack_require__) {let isarray = __webpack_require__("./node_modules/_isarray@2.0.5@isarray/index.js");console.log('isarray([1, 2, 3])=', isarray([1, 2, 3]));}),"dll-reference _dll_utils":(function (module, exports) {module.exports = _dll_utils;})});

实现DllPlugin.js

DllPlugin.js

plugins\DllPlugin.js

const DllEntryPlugin = require("./DllEntryPlugin");
class DllPlugin {constructor(options) {this.options = options;}apply(compiler) {compiler.hooks.entryOption.tap("DllPlugin", (context, entry) => {Object.keys(entry).forEach(name => {new DllEntryPlugin(context, entry[name],name).apply(compiler);});return true;});}
}
module.exports = DllPlugin;

DllEntryPlugin.js

plugins\DllEntryPlugin.js

const SingleEntryDependency = require("webpack/lib/dependencies/SingleEntryDependency");
const DllEntryDependency = require("./dependencies/DllEntryDependency");
const DllModuleFactory = require("./DllModuleFactory");
class DllEntryPlugin {constructor(context, entries, name) {this.context = context;// c:/aprepare/zhufeng_dll_preparethis.entries = entries;// ['isarray', 'is-promise']this.name = name; // utils}apply(compiler) {compiler.hooks.compilation.tap("DllEntryPlugin",(compilation, { normalModuleFactory }) => {const dllModuleFactory = new DllModuleFactory();compilation.dependencyFactories.set(DllEntryDependency,dllModuleFactory);compilation.dependencyFactories.set(SingleEntryDependency,normalModuleFactory);});compiler.hooks.make.tapAsync("DllEntryPlugin", (compilation, callback) => {compilation.addEntry(this.context,new DllEntryDependency(this.entries.map((entry) => new SingleEntryDependency(entry)),this.name//utils),this.name,//utilscallback);});}
}
module.exports = DllEntryPlugin;

DllModuleFactory.js

plugins\DllModuleFactory.js

const { Tapable } = require("tapable");
const DllModule = require("./DllModule");
class DllModuleFactory extends Tapable {constructor() {super();this.hooks = {};}create(data, callback) {const dependency = data.dependencies[0];callback(null,new DllModule(data.context,dependency.dependencies,// [SingleEntryDependency, SingleEntryDependency]dependency.name,//utilsdependency.type//'dll entry'));}
}
module.exports = DllModuleFactory;

DllEntryDependency.js

plugins\dependencies\DllEntryDependency.js

const Dependency = require("webpack/lib/Dependency");
class DllEntryDependency extends Dependency {constructor(dependencies, name) {super();this.dependencies = dependencies;//[SingleEntryDependency,SingleEntryDependency ]this.name = name;//utils}get type() {return "dll entry";}
}
module.exports = DllEntryDependency;

DllModule.js

plugins\DllModule.js

const { RawSource } = require("webpack-sources");
const Module = require("webpack/lib/Module");
class DllModule extends Module {constructor(context, dependencies, name, type) {super("javascript/dynamic", context);//c:/aprepare/zhufeng_dll_prepare2this.dependencies = dependencies;this.name = name;//utilsthis.type = type;//dll entry}identifier() {return `dll ${this.name}`;}readableIdentifier() {return `dll ${this.name}`;}build(options, compilation, resolver, fs, callback) {this.built = true;this.buildMeta = {};this.buildInfo = {};return callback();}source() {return new RawSource("module.exports = __webpack_require__;");}size() {return 12;}
}
module.exports = DllModule;

实现LibManifestPlugin.js

LibManifestPlugin.js

plugins\LibManifestPlugin.js

const path = require("path");
const asyncLib = require("neo-async");
class LibManifestPlugin {constructor(options) {this.options = options;}apply(compiler) {compiler.hooks.emit.tapAsync("LibManifestPlugin",(compilation, callback) => {asyncLib.forEach(compilation.chunks,(chunk, done) => {// c:aprepare/zhufeng_dll_prepare/dist/utils.manifest.jsonconst targetPath = this.options.path;const name =this.options.name;//_dll_utilslet content ={};for(let module of chunk.modulesIterable){if (module.libIdent) {const ident = module.libIdent({context:compiler.options.context});content[ident]= {id: module.id};}}const manifest = {name,content};//name=_dll_utilscompiler.outputFileSystem.mkdirp(path.dirname(targetPath), err => {compiler.outputFileSystem.writeFile(targetPath,JSON.stringify(manifest),done);});},callback);});}
}
module.exports = LibManifestPlugin;

DllPlugin.js

plugins\DllPlugin.js

const DllEntryPlugin = require("./DllEntryPlugin");
+const LibManifestPlugin = require("./LibManifestPlugin");
class DllPlugin {constructor(options) {this.options = options;}apply(compiler) {compiler.hooks.entryOption.tap("DllPlugin", (context, entry) => {Object.keys(entry).forEach(name => {new DllEntryPlugin(context, entry[name],name).apply(compiler);});return true;});
+        new LibManifestPlugin(this.options).apply(compiler);}
}
module.exports = DllPlugin;

实现DllReferencePlugin.js

DllReferencePlugin.js

plugins\DllReferencePlugin.js

const DelegatedSourceDependency = require("webpack/lib/dependencies/DelegatedSourceDependency");
const ExternalModuleFactoryPlugin = require("./ExternalModuleFactoryPlugin");
const DelegatedModuleFactoryPlugin = require("./DelegatedModuleFactoryPlugin");
class DllReferencePlugin {constructor(options) {this.options = options;}apply(compiler) {compiler.hooks.compilation.tap("DllReferencePlugin",(compilation, { normalModuleFactory }) => {compilation.dependencyFactories.set(DelegatedSourceDependency,normalModuleFactory);});compiler.hooks.compile.tap("DllReferencePlugin", ({normalModuleFactory}) => {let manifest = this.options.manifest;let name = manifest.name;//_dll_utilslet content = manifest.content;//{'is-promise':'','isarray':''}//外部模块  "dll-reference _dll_utils"引用window._dll_utilsconst externals = {};const source = "dll-reference " + name;//dll-reference _dll_utilsexternals[source] = name;//dll-reference _dll_utils=>_dll_utilsnew ExternalModuleFactoryPlugin("var", externals).apply(normalModuleFactory);new DelegatedModuleFactoryPlugin({source,context: compiler.options.context,content}).apply(normalModuleFactory);});}
}module.exports = DllReferencePlugin;

ExternalModuleFactoryPlugin.js

plugins\ExternalModuleFactoryPlugin.js

const ExternalModule = require('webpack/lib/ExternalModule');
class ExternalModuleFactoryPlugin{constructor(type, externals) {this.type = type;//varthis.externals = externals;//{"dll-reference _dll_utils":"_dll_utils"}}apply(normalModuleFactory) {//const globalType = this.type;normalModuleFactory.hooks.factory.tap("ExternalModuleFactoryPlugin",//传进去老的工厂函数,返回新的工厂函数factory => (data, callback) => {const dependency = data.dependencies[0];//DelegatedSourceDependencylet request = dependency.request;// "dll-reference _dll_utils"let value = this.externals[request];//_dll_utilsif(value){//如果是一个外部模块callback(null,new ExternalModule(value, 'var', dependency.request)//_dll_utils);}else{//否则 是个普通模块 走老的普通模块工厂的生产模块的逻辑factory(data, callback);}});}
}
module.exports = ExternalModuleFactoryPlugin;

DelegatedModuleFactoryPlugin.js

plugins\DelegatedModuleFactoryPlugin.js

const DelegatedModule = require("./DelegatedModule");
class DelegatedModuleFactoryPlugin {constructor(options) {this.options = options;options.type = options.type || "require";}apply(normalModuleFactory) {normalModuleFactory.hooks.module.tap("DelegatedModuleFactoryPlugin",module => {if (module.libIdent) {const request = module.libIdent(this.options);if (request && request in this.options.content) {const resolved = this.options.content[request];return new DelegatedModule(this.options.source,//dll-reference _dll_utilsresolved,//{"id":"./node_modules/_is-promise@4.0.0@is-promise/index.js"}module//老模块);}}return module;});}
}
module.exports = DelegatedModuleFactoryPlugin;

DelegatedModule.js

plugins\DelegatedModule.js

const { RawSource } = require("webpack-sources");
const DelegatedSourceDependency = require("webpack/lib/dependencies/DelegatedSourceDependency");
const Module = require("webpack/lib/Module");
class DelegatedModule extends Module {constructor(sourceRequest, data,originalRequest) {super("javascript/dynamic", null);this.sourceRequest = sourceRequest;//dll-reference _dll_utilsthis.request = data.id;//{"id":"./node_modules/_is-promise@4.0.0@is-promise/index.js"}this.originalRequest = originalRequest;//老模块}libIdent(options) {//模块ID还是老的模块IDreturn this.originalRequest.libIdent(options);}identifier() {return `delegated ${this.request} from ${this.sourceRequest}`;}readableIdentifier() {return `delegated ${this.request} from ${this.sourceRequest}`;}size(){return 42;}build(options, compilation, resolver, fs, callback) {this.built = true;this.buildMeta = {};this.buildInfo = {};this.delegatedSourceDependency = new DelegatedSourceDependency(this.sourceRequest);this.addDependency(this.delegatedSourceDependency);callback();}source() {let str = `module.exports = (__webpack_require__("${this.sourceRequest}"))(${JSON.stringify(this.request)});`;return new RawSource(str);}
}
module.exports = DelegatedModule;

autodll-webpack-plugin

  • autodll-webpack-plugin

webpack.config.js

const path = require('path');
const AutodllWebpackPlugin = require('autodll-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {mode:'development',devtool:false,entry:'./src/index.js',output:{path:path.resolve(__dirname,'dist'),//输出目录filename:'bundle.js',               //打包后的文件名publicPath:''                       //访问路径 },plugins:[new HtmlWebpackPlugin({inject: true,template: './src/index.html',}),new AutodllWebpackPlugin({inject: true,filename: '[name].dll.js',entry:{utils:['isarray','is-promise']}})]
}

plugin.js

node_modules_autodll-webpack-plugin@0.4.2@autodll-webpack-plugin\lib\plugin.js

+const HtmlWebpackPlugin = require("html-webpack-plugin");
+        compiler.hooks.compilation.tap('AutoDllPlugin', function (compilation) {
+          if (compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration) {
+            compilation.hooks.htmlWebpackPluginBeforeHtmlGeneration.tapAsync('AutoDllPlugin', doCompilation);
+          } else if (HtmlWebpackPlugin.getHooks && HtmlWebpackPlugin.getHooks(compilation)) {
+            HtmlWebpackPlugin.getHooks(compilation).beforeAssetTagGeneration.tapAsync('AutoDllPlugin', doCompilation);
+          }
+        });

这篇关于DllPlugin的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1056486

相关文章

前端性能优化三十一:花裤衩模板webpack DllPlugin

2. Webpack社区有两种方案: ①. CommonsChunkPlugin:a. webpack每次打包还需要去处理这些第三方库.b. 只是打包完后,能把第三方库和自己的代码分开,相当于单独打包第三方库.②. DLL(动态链接库):a. 指一个包含可由多个程序同时使用的代码库:(1). 借鉴了Windows系统的dll。一个dll包,就是一个纯纯的依赖库,它本身不能运行,是用来给你的app

vue项目,使用DllPlugin减少打包时间的配置

写在前面: 参考了许多资料,都差不多的,但是并不是很全,过程有点头疼   项目前提: index.html文件(在主目录下的) <!DOCTYPE html><html lang="zh-CN"><head><title></title><meta charset="UTF-8"><meta name="viewport" content="width=device-width,ini

DllPlugin - 打包性能优化点

背景 很多时候我们在开发业务代码的时候多多少少都引入了其他的第三方库,如 lodash.js , axios.js 等,那么在打包的时候呢每次打包就会重新打包这些引入的第三方库,那有没有办法让打包的时候能预先让这些第三方库打包好然后每次打包业务代码遇到引入第三方库的时候直接使用已打包好的第三方库的打包文件呢?那当然是有的啦!DllPlugin 作为提升打包性能的重要一环,同学们一定要认真掌握哦。