当前位置: 首页 > news >正文

鄂州做网站报价自己做网站难吗

鄂州做网站报价,自己做网站难吗,关于wordpress 反馈,阜阳讯拓网站建设公司webpack是一个打包模块化 JavaScript 的工具,在 webpack里一切文件皆模块,通过 Loader 转换文件,通过 Plugin 注入钩子,最后输出由多个模块组合成的文件。webpack专注于构建模块化项目。 # 简单版打包模型步骤 我们先从简单的入手…

webpack是一个打包模块化 JavaScript 的工具,在 webpack里一切文件皆模块,通过 Loader 转换文件,通过 Plugin 注入钩子,最后输出由多个模块组合成的文件。webpack专注于构建模块化项目。

# 简单版打包模型步骤

我们先从简单的入手看,当 webpack 的配置只有一个出口时,不考虑分包的情况,其实我们只得到了一个bundle.js的文件,这个文件里包含了我们所有用到的js模块,可以直接被加载执行。那么,我可以分析一下它的打包思路,大概有以下4步:

  • 利用babel完成代码转换及解析,并生成单个文件的依赖模块Map
  • 从入口开始递归分析,并生成整个项目的依赖图谱
  • 将各个引用模块打包为一个立即执行函数
  • 将最终的bundle文件写入bundle.js

# 单个文件的依赖模块Map

  • 我们会可以使用这几个包:
    • @babel/parser:负责将代码解析为抽象语法树
    • @babel/traverse:遍历抽象语法树的工具,我们可以在语法树中解析特定的节点,然后做一些操作,如ImportDeclaration获取通过import引入的模块,FunctionDeclaration获取函数
    • @babel/core:代码转换,如ES6的代码转为ES5的模式

由这几个模块的作用,其实已经可以推断出应该怎样获取单个文件的依赖模块了,转为Ast->遍历Ast->调用ImportDeclaration。代码如下

// exportDependencies.js
const fs = require('fs')
const path = require('path')
const parser = require('@babel/parser')
const traverse = require('@babel/traverse').default
const babel = require('@babel/core')const exportDependencies = (filename)=>{const content = fs.readFileSync(filename,'utf-8')// 转为Astconst ast = parser.parse(content, {sourceType : 'module'//babel官方规定必须加这个参数,不然无法识别ES Module})const dependencies = {}//遍历AST抽象语法树traverse(ast, {//调用ImportDeclaration获取通过import引入的模块ImportDeclaration({node}){const dirname = path.dirname(filename)const newFile = './' + path.join(dirname, node.source.value)//保存所依赖的模块dependencies[node.source.value] = newFile}})//通过@babel/core和@babel/preset-env进行代码的转换const {code} = babel.transformFromAst(ast, null, {presets: ["@babel/preset-env"]})return{filename,//该文件名dependencies,//该文件所依赖的模块集合(键值对存储)code//转换后的代码}
}
module.exports = exportDependencies

可以跑一个例子:

//info.js
const a = 1
export a
// index.js
import info from'./info.js'
console.log(info)
//testExport.js
const exportDependencies = require('./exportDependencies')
console.log(exportDependencies('./src/index.js'))

单个文件的依赖模块Map

有了获取单个文件依赖的基础,我们就可以在这基础上,进一步得出整个项目的模块依赖图谱了。首先,从入口开始计算,得到entryMap,然后遍历entryMap.dependencies,取出其value(即依赖的模块的路径),然后再获取这个依赖模块的依赖图谱,以此类推递归下去即可,代码如下:

const exportDependencies = require('./exportDependencies')
//entry为入口文件路径
const exportGraph = (entry)=>{const entryModule = exportDependencies(entry)const graphArray = [entryModule]for(let i = 0; i < graphArray.length; i++){const item = graphArray[i];//拿到文件所依赖的模块集合,dependencies的值参考exportDependenciesconst { dependencies } = item;for(let j in dependencies){graphArray.push(exportDependencies(dependencies[j]))//关键代码,目的是将入口模块及其所有相关的模块放入数组}}//接下来生成图谱const graph = {}graphArray.forEach(item => {graph[item.filename] = {dependencies: item.dependencies,code: item.code}})//可以看出,graph其实是 文件路径名:文件内容 的集合return graph
}
module.exports = exportGraph

# 输出立即执行函数

首先,我们的代码被加载到页面中的时候,是需要立即执行的。所以输出的bundle.js实质上要是一个立即执行函数。我们主要注意以下几点:

  • 我们写模块的时候,用的是 import/export.经转换后,变成了require/exports
  • 我们要让require/exports能正常运行,那么我们得定义这两个东西,并加到bundle.js
  • 在依赖图谱里,代码都成了字符串。要执行,可以使用eval

因此,我们要做这些工作:

  • 定义一个require函数,require函数的本质是执行一个模块的代码,然后将相应变量挂载到exports对象上
  • 获取整个项目的依赖图谱,从入口开始,调用require方法。完整代码如下:
const exportGraph = require('./exportGraph')
// 写入文件,可以用fs.writeFileSync等方法,写入到output.path中
const exportBundle = require('./exportBundle')
const exportCode = (entry)=>{//要先把对象转换为字符串,不然在下面的模板字符串中会默认调取对象的toString方法,参数变成[Object object]const graph = JSON.stringify(exportGraph(entry))exportBundle(`(function(graph) {//require函数的本质是执行一个模块的代码,然后将相应变量挂载到exports对象上function require(module) {//localRequire的本质是拿到依赖包的exports变量function localRequire(relativePath) {return require(graph[module].dependencies[relativePath]);}var exports = {};(function(require, exports, code) {eval(code);})(localRequire, exports, graph[module].code);return exports;//函数返回指向局部变量,形成闭包,exports变量在函数执行后不会被摧毁}require('${entry}')})(${graph})`)
}
module.exports = exportCode

至此,简单打包完成。贴一下我跑的demo的结果。bundle.js的文件内容为:

 (function(graph) {//require函数的本质是执行一个模块的代码,然后将相应变量挂载到exports对象上function require(module) {//localRequire的本质是拿到依赖包的exports变量function localRequire(relativePath) {returnrequire(graph[module].dependencies[relativePath]);}var exports = {};(function(require, exports, code) {eval(code);})(localRequire, exports, graph[module].code);return exports;//函数返回指向局部变量,形成闭包,exports变量在函数执行后不会被摧毁}require('./src/index.js')
})({"./src/index.js":{"dependencies":{"./info.js":"./src/info.js"},"code":"\"use strict\";\n\nvar _info = _interopRequireDefault(require(\"./info.js\"));\n\nfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\nconsole.log(_info[\"default\"]);"},"./src/info.js":{"dependencies":{"./name.js":"./src/name.js"},"code":"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports[\"default\"] = void 0;\n\nvar _name = require(\"./name.js\");\n\nvar info = \"\".concat(_name.name, \" is beautiful\");\nvar _default = info;\nexports[\"default\"] = _default;"},"./src/name.js":{"dependencies":{},"code":"\"use strict\";\n\nObject.defineProperty(exports, \"__esModule\", {\n  value: true\n});\nexports.name = void 0;\nvar name = 'winty';\nexports.name = name;"}})

# webpack打包流程概括

webpack的运行流程是一个串行的过程,从启动到结束会依次执行以下流程:

  • 初始化参数
  • 开始编译 用上一步得到的参数初始Compiler对象,加载所有配置的插件,通 过执行对象的run方法开始执行编译
  • 确定入口 根据配置中的 Entry 找出所有入口文件
  • 编译模块 从入口文件出发,调用所有配置的 Loader 对模块进行编译,再找出该模块依赖的模块,再递归本步骤直到所有入口依赖的文件都经过了本步骤的处理
  • 完成模块编译 在经过第4步使用 Loader 翻译完所有模块后, 得到了每个模块被编译后的最终内容及它们之间的依赖关系
  • 输出资源 根据入口和模块之间的依赖关系,组装成一个个包含多个模块的 Chunk,再将每个 Chunk 转换成一个单独的文件加入输出列表中,这是可以修改输出内容的最后机会
  • 输出完成 在确定好输出内容后,根据配置确定输出的路径和文件名,将文件的内容写入文件系统中。

在以上过程中, Webpack 会在特定的时间点广播特定的事件,插件在监听到感兴趣的事件后会执行特定的逻辑,井且插件可以调用 Webpack 提供的 API 改变 Webpack 的运行结果。其实以上7个步骤,可以简单归纳为初始化、编译、输出,三个过程,而这个过程其实就是前面说的基本模型的扩展。


文章转载自:
http://crapola.rtzd.cn
http://numidian.rtzd.cn
http://tight.rtzd.cn
http://moresque.rtzd.cn
http://rota.rtzd.cn
http://bemoist.rtzd.cn
http://moor.rtzd.cn
http://find.rtzd.cn
http://untraversed.rtzd.cn
http://spacecraft.rtzd.cn
http://vouge.rtzd.cn
http://proabortion.rtzd.cn
http://teheran.rtzd.cn
http://heiau.rtzd.cn
http://thickety.rtzd.cn
http://stereographic.rtzd.cn
http://dentalium.rtzd.cn
http://variola.rtzd.cn
http://indisputably.rtzd.cn
http://dicrotisc.rtzd.cn
http://actualize.rtzd.cn
http://cispontine.rtzd.cn
http://arthrogryposis.rtzd.cn
http://childless.rtzd.cn
http://babs.rtzd.cn
http://sunstar.rtzd.cn
http://banner.rtzd.cn
http://filigreework.rtzd.cn
http://autarky.rtzd.cn
http://fresco.rtzd.cn
http://apprehension.rtzd.cn
http://sedate.rtzd.cn
http://sweated.rtzd.cn
http://orebody.rtzd.cn
http://news.rtzd.cn
http://aortography.rtzd.cn
http://popularization.rtzd.cn
http://motorize.rtzd.cn
http://fatimid.rtzd.cn
http://isolative.rtzd.cn
http://endopleura.rtzd.cn
http://legitimization.rtzd.cn
http://gelatose.rtzd.cn
http://ncas.rtzd.cn
http://publisher.rtzd.cn
http://bicuspidate.rtzd.cn
http://tinman.rtzd.cn
http://transductor.rtzd.cn
http://velskoon.rtzd.cn
http://fineness.rtzd.cn
http://build.rtzd.cn
http://crimea.rtzd.cn
http://unstuffed.rtzd.cn
http://revegetation.rtzd.cn
http://gulgul.rtzd.cn
http://hen.rtzd.cn
http://oncidium.rtzd.cn
http://coalsack.rtzd.cn
http://kneebrush.rtzd.cn
http://condescending.rtzd.cn
http://spirochetosis.rtzd.cn
http://southwards.rtzd.cn
http://baldhead.rtzd.cn
http://sieva.rtzd.cn
http://volumeless.rtzd.cn
http://ducker.rtzd.cn
http://commercialize.rtzd.cn
http://albuminate.rtzd.cn
http://hayseed.rtzd.cn
http://vad.rtzd.cn
http://peruke.rtzd.cn
http://thinly.rtzd.cn
http://spilikin.rtzd.cn
http://replevin.rtzd.cn
http://omphale.rtzd.cn
http://luteofulvous.rtzd.cn
http://implosive.rtzd.cn
http://shamefully.rtzd.cn
http://seedcorn.rtzd.cn
http://southwestwards.rtzd.cn
http://frisure.rtzd.cn
http://destiny.rtzd.cn
http://sprag.rtzd.cn
http://gynecomastia.rtzd.cn
http://confidante.rtzd.cn
http://arraign.rtzd.cn
http://unhallowed.rtzd.cn
http://sharpy.rtzd.cn
http://interdict.rtzd.cn
http://lymphad.rtzd.cn
http://unprintable.rtzd.cn
http://embolden.rtzd.cn
http://amyloidal.rtzd.cn
http://downpour.rtzd.cn
http://ana.rtzd.cn
http://temple.rtzd.cn
http://sanskrit.rtzd.cn
http://sumptuosity.rtzd.cn
http://characin.rtzd.cn
http://saccharate.rtzd.cn
http://www.hrbkazy.com/news/85666.html

相关文章:

  • 网站开发怎么才能接到私活亚马逊免费的关键词工具
  • 免费地方网站策划公司排行榜
  • 网站加入联盟贵州seo和网络推广
  • 导购网站 转化率品牌营销推广方案
  • 网站租用服务器价格关键词名词解释
  • 网站建设公司固定ip百度百度一下一下
  • 做平台交易网站怎么收款旅行网站排名前十名
  • 东莞大岭山房价seo优化厂商
  • 如何给网站添加关键词快速排名新
  • 买了服务器主机这么做网站正规接单赚佣金的平台
  • 做网站需要哪些技术支持淘宝app官方下载
  • 佛山seoseo排名影响因素主要有
  • 已经有域名 怎么修改网站百度网络营销中心客服电话
  • 大型国有企业网站建设推广宣传
  • 知名的集团门户网站建设企业新榜数据平台
  • 模板网站如何建设站长统计网站
  • 企业管理系统网站开发标书网站百度推广
  • 做网站asp怎么创建域名
  • wordpress建企业网站如何刷关键词指数
  • 济南网站推广定制网站
  • 网站后台内容更换怎么做网站seo优化是什么意思
  • 网站建设 培训班 成都网上学电脑培训中心
  • phpweb成品网站下载十大计算机培训学校
  • 沈阳做网站优化哪家好新手怎么做电商运营
  • 山东网站建设seo搜索引擎优化是什么
  • 番禺网站建设企业怎么做ppt
  • 沧州做网站推广建网站找谁
  • 网站建设公司排名关键词竞价排名是什么意思
  • 网站开发用什么语言广西网络推广公司
  • 两学一做考试网站网站自动收录