Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 Warning: error_log(/data/www/wwwroot/hmttv.cn/caches/error_log.php): failed to open stream: Permission denied in /data/www/wwwroot/hmttv.cn/phpcms/libs/functions/global.func.php on line 537 亚洲tv精品一区二区三区,日本苍井一级毛片,久久精品美女

          整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          如何寫一個webpack插件(一)

          如何寫一個webpack插件(一)

          最近由于用著html-webpack-plugin覺得很不爽,于是乎想自己動手寫一個插件。原以為像gulp插件一樣半天上手一天寫完,但令人郁悶的是完全找不到相關的文章。一進官方文檔卻是被嚇傻了。首先是進入how to write a plugin看了一頁簡單的介紹。然后教程會告訴你,你需要去了解compiler和compilation這兩個對象,才能更好地寫webpack的插件,然后作者給了github的鏈接給你,讓你去看源代碼,我暈。不過幸好最后給了一個plugins的API文檔,才讓我開發的過程中稍微有點頭緒。

          how to write a plugin這個教程還是可以好好看看的,尤其是那個simple example,它會教你在compilation的emit事件或之前,將你需要生成的文件放到webpack的compilation.assets里,這樣就可以借助webpack的力量幫你生成文件,而不需要自己手動去寫fs.writeFileSync。

          主要就是這段代碼

          compilation.assets['filelist.md']={
                source: function {
                  return filelist;
                },
                size: function {
                  return filelist.length;
                }
          };

          基本特性介紹

          首先,定義一個函數func,用戶設置的options基本就在這里處理。

          其次,需要設一個func.prototype.apply函數。這個函數是提供給webpack運行時調用的。webpack會在這里注入compiler對象。

          輸出complier對象,你會看到這一長串的內容,初步一看,我看出了兩大類(有補充的可以告訴我)。一個webpack運行時的參數,例如_plugins,這些數組里的函數應該是webpack內置的函數,用于在compiltion,this-compilation和should-emit事件觸發時調用的。另一個是用戶寫在webpack.config.js里的參數。隱約覺得這里好多未來都可能會是webpack暴露給用戶的接口,使webpack的定制化功能更強大。

          Compiler {
            _plugins:
             { compilation: [ [Function], [Function], [Function], [Function] ],
               'this-compilation': [ [Function: bound ] ],
               'should-emit': [ [Function] ] },
            outputPath: '',
            outputFileSystem: null,
            inputFileSystem: null,
            recordsInputPath: null,
            recordsOutputPath: null,
            records: {},
            fileTimestamps: {},
            contextTimestamps: {},
            resolvers:
             { normal: Tapable { _plugins: {}, fileSystem: null },
               loader: Tapable { _plugins: {}, fileSystem: null },
               context: Tapable { _plugins: {}, fileSystem: null } },
            parser:
             Parser {
               _plugins:
                { 'evaluate Literal': [Object],
                  'evaluate LogicalExpression': [Object],
                  'evaluate BinaryExpression': [Object],
                  'evaluate UnaryExpression': [Object],
                  'evaluate typeof undefined': [Object],
                  'evaluate Identifier': [Object],
                  'evaluate MemberExpression': [Object],
                  'evaluate CallExpression': [Object],
                  'evaluate CallExpression .replace': [Object],
                  'evaluate CallExpression .substr': [Object],
                  'evaluate CallExpression .substring': [Object],
                  'evaluate CallExpression .split': [Object],
                  'evaluate ConditionalExpression': [Object],
                  'evaluate ArrayExpression': [Object],
                  'expression Spinner': [Object],
                  'expression ScreenMod': [Object] },
               options: undefined },
            options:
             { entry:
                { 
                  'index': '/Users/mac/web/src/page/index/main.js' },
               output:
                { publicPath: '/homework/features/model/',
                  path: '/Users/mac/web/dist',
                  filename: 'js/[name].js',
                  libraryTarget: 'var',
                  sourceMapFilename: '[file].map[query]',
                  hotUpdateChunkFilename: '[id].[hash].hot-update.js',
                  hotUpdateMainFilename: '[hash].hot-update.json',
                  crossOriginLoading: false,
                  hashFunction: 'md5',
                  hashDigest: 'hex',
                  hashDigestLength: 20,
                  sourcePrefix: '\t',
                  devtoolLineToLine: false },
               externals: { react: 'React' },
               module:
                { loaders: [Object],
                  unknownContextRequest: '.',
                  unknownContextRecursive: true,
                  unknownContextRegExp: /^\.\/.*$/,
                  unknownContextCritical: true,
                  exprContextRequest: '.',
                  exprContextRegExp: /^\.\/.*$/,
                  exprContextRecursive: true,
                  exprContextCritical: true,
                  wrappedContextRegExp: /.*/,
                  wrappedContextRecursive: true,
                  wrappedContextCritical: false },
               resolve:
                { extensions: [Object],
                  alias: [Object],
                  fastUnsafe: ,
                  packageAlias: 'browser',
                  modulesDirectories: [Object],
                  packageMains: [Object] },
               plugins:
                [ [Object],
                  [Object],
                  [Object],
                  [Object],
                  NoErrorsPlugin {},
                  [Object],
                  [Object] ],
               devServer: { port: 8081, contentBase: './dist' },
               context: '/Users/mac/web/',
               watch: true,
               debug: false,
               devtool: false,
               cache: true,
               target: 'web',
               node:
                { console: false,
                  process: true,
                  global: true,
                  setImmediate: true,
                  __filename: 'mock',
                  __dirname: 'mock' },
               resolveLoader:
                { fastUnsafe: ,
                  alias: {},
                  modulesDirectories: [Object],
                  packageMains: [Object],
                  extensions: [Object],
                  moduleTemplates: [Object] },
               optimize: { occurenceOrderPreferEntry: true } },
            context: '/Users/mac/web/' }

          除此以外,compiler還有一些如run, watch-run的方法以及compilation, normal-module-factory對象。我目前用到的,主要是compilation。其它的等下一篇有機會再說。

          對比起compiler還有compiler.plugin函數。這個相當于是插件可以進行處理的webpack的運行中的一些任務點,webpack就是完成一個又一個任務而完成整個打包構建過程的。如make是最開始的起點, complie就是編譯任務點,after-complie是編譯完成,emit是即將準備生成文件,after-emit是生成文件之后等等,前面幾個都是比較生動形象的任務點。

          至于compilation,它繼承于compiler,所以能拿到一切compiler的內容(所以你也會看到webpack的options),而且也有plugin函數來接入任務點。在compiler.plugin('emit')任務點輸出compilation,會得到大致下面的對象數據,因為實在太長,我只保留了最重要的assets部份:

          assetsCompilation {
            assets:
             { 'js/index/main.js':
                CachedSource {
                  _source: [Object],
                  _cachedSource: undefined,
                  _cachedSize: undefined,
                  _cachedMaps: {} } },
            errors: ,
            warnings: ,
            children: ,
            dependencyFactories:
             ArrayMap {
               keys:
                [ [Object],
                  [Function: MultiEntryDependency],
                  [Function: SingleEntryDependency],
                  [Function: LoaderDependency],
                  [Object],
                  [Function: ContextElementDependency],
               values:
                [ NullFactory {},
                  [Object],
                  NullFactory {} ] },
            dependencyTemplates:
             ArrayMap {
               keys:
                [ [Object],
                  [Object],
                  [Object] ],
               values:
                [ ConstDependencyTemplate {},
                  RequireIncludeDependencyTemplate {},
                  NullDependencyTemplate {},
                  RequireEnsureDependencyTemplate {},
                  ModuleDependencyTemplateAsRequireId {},
                  AMDRequireDependencyTemplate {},
                  ModuleDependencyTemplateAsRequireId {},
                  AMDRequireArrayDependencyTemplate {},
                  ContextDependencyTemplateAsRequireCall {},
                  AMDRequireDependencyTemplate {},
                  LocalModuleDependencyTemplate {},
                  ModuleDependencyTemplateAsId {},
                  ContextDependencyTemplateAsRequireCall {},
                  ModuleDependencyTemplateAsId {},
                  ContextDependencyTemplateAsId {},
                  RequireResolveHeaderDependencyTemplate {},
                  RequireHeaderDependencyTemplate {} ] },
            fileTimestamps: {},
            contextTimestamps: {},
            name: undefined,
            _currentPluginApply: undefined,
            fullHash: 'f4030c2aeb811dd6c345ea11a92f4f57',
            hash: 'f4030c2aeb811dd6c345',
            fileDependencies: [ '/Users/mac/web/src/js/index/main.js' ],
            contextDependencies: ,
            missingDependencies:  }

          assets部份重要是因為如果你想借助webpack幫你生成文件,你需要像官方教程how to write a plugin在assets上寫上對應的文件信息。

          除此以外,compilation.getStats這個函數也相當重要,能得到生產文件以及chunkhash的一些信息,如下:

          assets{ errors: ,
            warnings: ,
            version: '1.12.9',
            hash: '5a5c71cb2accb8970bc3',
            publicPath: 'xxxxxxxxxx',
            assetsByChunkName: { 'index/main': 'js/index/index-4c0c16.js' },
            assets:
             [ { name: 'js/index/index-4c0c16.js',
                 size: 453,
                 chunks: [Object],
                 chunkNames: [Object],
                 emitted: undefined } ],
            chunks:
             [ { id: 0,
                 rendered: true,
                 initial: true,
                 entry: true,
                 extraAsync: false,
                 size: 221,
                 names: [Object],
                 files: [Object],
                 hash: '4c0c16e8af4d497b90ad',
                 parents: ,
                 origins: [Object] } ],
            modules:
             [ { id: 0,
                 identifier: 'multi index/main',
                 name: 'multi index/main',
                 index: 0,
                 index2: 1,
                 size: 28,
                 cacheable: true,
                 built: true,
                 optional: false,
                 prefetched: false,
                 chunks: [Object],
                 assets: ,
                 issuer: null,
                 profile: undefined,
                 failed: false,
                 errors: 0,
                 warnings: 0,
                 reasons:  },
               { id: 1,
                 identifier: '/Users/mac/web/node_modules/babel-loader/index.js?presets=es2015&presets=react!/Users/mac/web/src/js/main/index.js',
                 name: './src/js/index/main.js',
                 index: 1,
                 index2: 0,
                 size: 193,
                 cacheable: true,
                 built: true,
                 optional: false,
                 prefetched: false,
                 chunks: [Object],
                 assets: ,
                 issuer: 'multi index/main',
                 profile: undefined,
                 failed: false,
                 errors: 0,
                 warnings: 0,
                 reasons: [Object],
                 source: ''  // 具體文件內容}
           ],
            filteredModules: 0,
            children:  }

          這里的chunks數組里,是對應會生成的文件,以及md5之后的文件名和路徑,里面還有文件對應的chunkhash(每個文件不同,但如果你使用ExtractTextPlugin將css文件獨立出來的話,它會與require它的js入口文件共享相同的chunkhash),而assets.hash則是統一的hash,對每個文件都一樣。值得關注的是chunks里的每個文件,都有source這一項目,提供給開發者直接拿到源文件內容(主要是js,如果是css且使用ExtractTextPlugin,則請自行打印出來參考)。

          例子

          接下來,會以最近我寫的一個插件html-res-webpack-plugin作為引子,來介紹基本的寫插件原理。插件的邏輯就寫在index.js里。

          首先,將用戶輸入的參數在定好的函數中處理,HtmlResWebpackPlugin。

          然后,新增apply函數,在里面寫好插件需要切入的webpack任務點。目前HtmlResWebpackPlugin插件只用到emit這個任務點,其它幾個僅作為演示。

          第三步,調用addFileToWebpackAsset方法,寫compilation.assets,借助webpack生成html文件。

          第四步,在開發模式下(isWatch=true),直接生成html,但在生產模式下(isWatch=true),插件會開始對靜態資源(js,css)進行md5或者內聯。

          第五步,調用findAssets方法是為了通過compilation.getStats拿到的數據,去匹配對應的靜態資源,還有找到對應的哈希(是chunkhash還是hash)。

          最六步,調用addAssets方法,對靜態資源分別做內聯或者md5文件處理。內聯資源的函數是inlineRes,你會看到我使用了compilation.assets[hashFile].source 及 compilation.assets[hashFile].children[1]._value。前者是針對于js的,后者是針對使用了ExtractTextPlugin的css資源。

          最后一步,即是內聯和md5完成后,再更新一下compilation.assets中對應生成html的source內容,才能正確地生成內聯和md5后的內容。

          后記

          有興趣可以試用一下html-res-webpack-plugin這個插件(為什么要寫一個新的html生成插件,我在readme里寫了,此處不贅述),看看有哪些用得不爽之處。目前只是第一版,還不適合用于生產環境。希望第二版的時候能適用于更多的場景,以及性能更好。到是,我也會寫第二篇插件開發文章,將本文還沒提到的地方一一補充完整。也歡迎大家在這里發貼,或者指出本人的謬誤之處。

          018 眼看就要過去了,今年的你相較去年技術上有怎樣的收獲呢?

          不論你是正在自學前端遇到了瓶頸,還是對某些技術熟練掌握但某些還未涉足,都希望這份清單能對你有所幫助。由于頭條不讓站外鏈接,可以自行復制來源鏈接或者文末查看更多

          作者:AlienZHOU

          來源:

          https://github.com/alienzhou/frontend-tech-list

          前端技術清單

          學習文章的知識往往是碎片化的。而前端涉及到的面很廣,這些知識如果不進行有效梳理,則無法相互串聯、形成體系。因此,我結合工作體會將抽象出了一些前端基礎能力,并將看過、寫過的一些不錯的文章進行整理,形成了一份(純)前端技術清單。

          不論你是正在自學前端,還是對前端某些技術熟練掌握但某些還未涉足,我都希望這份清單能幫助你 review 一些前端的基礎能力。

          0. 年度報告

          • 2018 前端工具調查報告
          • 2018 JavaScript 調查報告

          1. 基礎拾遺

          溫故而知新,不知則習之,是以牢固根基。

          1.1. JavaScript

          • You-Dont-Know-JS [英]
          • JavaScript 基礎運行機制:
          • JS 引擎、運行時與調用棧概述 [英]
          • V8 引擎簡介 [英]
          • 內存管理與4中常見的泄漏 [英]
          • Event Loop(面試里總會有一題 Event Loop…):
          • 從 Event Loop 規范探究 JavaScript 異步及瀏覽器更新渲染時機
          • 異步之 Event Loop [英]
          • NodeJS 中的 Event Loop、Timers 與 process.nextTick() [英]
          • Tasks、Microtasks、Queues 與Schedules [英]
          • Web Workers 及其5個常見使用場景 [英]
          • 如何避免 async/await 地獄 [英]
          • “回調地獄”的解決思路匯總

          1.2. CSS

          • You-Need-to-Know-CSS
          • CSS布局指南
          • 在 (S)CSS 中實現主題功能的 4? 種方法 [英]
          • CSS 中的各類換行處理方式 [英]:處理經典的換行問題
          • 瀏覽器將rem轉成px時有精度誤差怎么辦?
          • 精準操控的滾動體驗,淺談新標準 Scroll Snap
          • 如何完美實現一個非button元素的按鈕 [英]
          • 巧用 CSS Grid 來創建橫向滾動容器 [英]
          • 如何處理內聯元素中的空隙 [英]
          • CSS Stacking Context 里那些鮮為人知的坑

          1.3. 瀏覽器

          • 瀏覽器的工作原理
          • 現代瀏覽器內部是如何運行的:
          • Chrome瀏覽器概覽
          • 瀏覽時發生了什么?
          • 渲染進程的內部工作原理
          • compositor是如何來提高交互性能的?
          • 完整的頁面生命周期 API 介紹 [英]
          • 四個新的觀察者:Intersection / Mutation / Resize / Performance (Observer)
          • 渲染引擎工作方式及優化建議 [英]
          • 瀏覽器內核渲染:重建引擎
          • 跨域解決方案匯總

          2. 工程化與工具

          軟件規模的擴大帶來了工程化的需求,前端也不例外。隨著 NodeJS 的出現,前端工程師可以使用熟悉的 JS 快速開發所需的工具。工具鏈生態的繁榮也是前端圈繁榮的一個寫照。

          2.1. webpack

          • webpack 中的 Chunk 關系圖算法 [英]
          • webpack 進階系列文章
          • 編譯優化:
          • 如何提升大型項目中 webpack 的性能 [英]
          • 運行時優化:Separating a Manifest [英]
          • 在 webpack 中使用 <link rel=”prefetch/preload”> [英]
          • 如何更好使用 webpack tree-shaking
          • 關于 webpack 編譯緩存的討論:
          • mzgoddard's comment
          • [spec: webpack 5] - A module disk cache between build processes

          2.2. Gulp

          • Gulp 4 簡介 [英]
          • 基于Gulp的多頁面應用實踐指南

          2.3. Linter

          • JS Linter 進化史
          • 為何要在項目匯總使用 ESLint [英]

          2.4. 靜態類型(Typescript/Flow)

          • Typescript 總體架構 [英]
          • 為什么要在 JavaScript 中進行靜態類型檢查:
          • 第一部分
          • 第二、三部分
          • 第四部分

          2.5. Babel

          • Babel 用戶手冊
          • Babel 插件手冊

          2.6. CSS預處理與模塊化

          • CSS 進化史 [英]
          • CSS 模塊化方案系列

          3. 性能優化

          性能優化其實就是在理解瀏覽器的基礎上“因地制宜”,因此可以配合1.3節“瀏覽器”部分進行理解。

          強烈推薦把 Google Web 上性能優化 Tab 中的文章都通讀一遍,其基本涵蓋了現代瀏覽器中性能優化的所有點,非常系統。下面也摘錄了其中一些個人認為非常不錯的篇幅。

          3.1. 加載性能

          • PRPL 模式 [英]
          • 圖片懶加載完全指南 [英]
          • 使用 Intersection Observer 來懶加載圖片 [英]
          • 圖片與視頻懶加載的詳細指南 [英]
          • 使用 Application Shell 架構來實現秒開應用 [英]

          3.2. 運行時性能

          • 避免大型、復雜的布局和布局抖動 [英]
          • 什么導致強制同步布局(reflow)? [英]
          • 如何診斷強制同步布局 [英]
          • 無線性能優化:Composite
          • 如何不擇手段提升scroll事件的性能
          • 使用 passive event listener 來提高滾動流暢性 [英]
          • 節流和去抖(throttle & debounce):
          • JavaScript 函數節流和函數去抖應用場景辨析
          • underscore 函數去抖的實現
          • requestIdleCallback - 一個強大而神器的 API:
          • requestIdleCallback使用入門 [英]
          • Idle Until Urgent [英]:requestIdleCallback的妙用

          3.3. 前端緩存

          • Web 緩存簡介:以購買牛奶的為例 [英]
          • 大話前端緩存 [英]
          • 緩存(一)—— 緩存總覽:從性能優化的角度看緩存
          • 緩存(二)—— 瀏覽器緩存機制:強緩存、協商緩存
          • 緩存(三)—— 數據存儲:cookie、Storage、indexedDB

          3.4. 性能調試與實踐

          • 使用 Chrome DevTools 提升頁面速度 [英]:Chrome DevTools實操講解
          • 了解 DevTools 中的 Resource Timing
          • 淘寶新勢力周H5性能優化實戰
          • 優化打包策略來提升頁面加載速度
          • Chrome DevTools 中你可能不知道的調試技巧
          • 前端性能測量 [英]

          3.5. 性能指標

          • 以用戶為中心的前端性能指標 [英]:前端性能指標的來龍去脈
          • DOMContentLoaded:
          • 你不知道的 DOMContentLoaded
          • Deciphering the Critical Rendering Path [英]
          • FP (First Paint):
          • Chrome的First Paint
          • FCP (First Contentful Paint):
          • First Contentful Paint Explained [英]
          • First Contentful Paint [英]
          • FMP (First Meaningful Paint):
          • Chrome 中的 First Meaningful Paint
          • Time to First Meaningful Paint
          • TTI (Time to interactive):
          • Time to Interactive Explainer
          • 衡量用戶體驗的新標準
          • TTFB (Time To First Byte):
          • TTFB,以及頁面加載的時間節點
          • FID (First Input Delay):
          • First Input Delay
          • Speed Index:
          • WebPagetest: Speed Index

          4. 安全

          很多安全風險老生常談,但是往往到出現問題時,才會被重視或者意識到。

          • 8大前端安全問題上篇
          • 8大前端安全問題下篇
          • 概念講解:編碼、加密、哈希與混淆 [英]
          • 常見 Web 安全攻防總結

          4.1. XSS

          • 如何防止XSS攻擊?

          4.2. CSRF

          • 如何防止CSRF攻擊?
          • Site Isolation [英]:Chrome的新特性

          4.3. CSP

          • Content Security Policy 入門教程
          • Content Security Policy (CSP) [英]

          4.4. HTTPS

          • 圖文還原 HTTPS 原理
          • 淺談有贊全站 HTTPS 推進

          4.5. 安全實錄

          • About rel=noopener [英]:打開一個新頁面是如何帶來安全隱患的
          • 一種新型的“釣魚”方式 [英]
          • 一個媒體文件請求引發的跨站風險 [英]
          • Mitigating Spectre [英]: Chrome 中的跨站安全問題

          5. 自動化測試

          自動化測試是軟件工程的重要部分之一,但卻極容易被忽視。

          • 2018 前端自動化測試綜述 [英]
          • 測試你的前端代碼(介紹篇)[英]

          5.1. 單元測試

          • 測試你的前端代碼(單元測試篇)[英]
          • Fakes、Mocks 以及 Stubs 概念明晰
          • 測試覆蓋(率)到底有什么用?

          5.2. 端到端測試 (E2E)

          • 測試你的前端代碼(E2E 測試篇)[英]
          • 什么是一個好的 E2E 測試?[英]
          • 平衡單元測試和端到端測試
          • 對過多的 E2E 測試說“不” [英]

          5.3. 其他

          • 測試你的前端代碼(集成測試篇)[英]
          • 測試你的前端代碼(可視化測試篇)[英]

          6. 框架與類庫

          如果說基礎知識是道,那框架與工具可能就是術;學習與理解它們,但千萬不要成為它們的奴隸。

          6.1. React

          • React 底層揭秘 [英]
          • 你所需要知道的 React 細節
          • React Fiber 架構
          • React 16 Fiber 源碼速覽
          • React 是怎樣煉成的:React早期的進化之路
          • 從零開始實現一個React:
          • 1. JSX和虛擬DOM
          • 2. 組件和生命周期
          • 3. diff算法
          • 4. 異步的setState
          • 「react技術棧」單頁應用實踐快速入門

          6.2. Vue

          • 深入淺出 - vue變化偵測原理
          • Vue 模板編譯原理

          6.3. Redux

          • 重新設計 Redux [英]:Rematch
          • 如何用 GraphQL 來替代 Redux [英]
          • 解讀 Redux 的設計思路與用法
          • (Redux)應用構建的三個原則 [英]

          6.4. RxJS

          • ReactiveX 官網:寶石圖真的非常形象易讀
          • 響應式編程,是明智的選擇
          • 圖解RxJS [英]
          • 調試RxJS:Tooling [英]
          • 調試RxJS:Logging [英]

          7. 新技術/方向

          前端領域新技術、新方向層出不窮,這里匯總一些新技術方向;作為開發者需要多了解但是不要盲從

          7.1. PWA

          • PWA 學習與實踐系列
          • Service Worker 入門簡介 [英]
          • PWA 在 iOS 平臺上的特殊問題 [英]
          • 在你的 PWA 中小心使用 iOS 的 meta 標簽 [英]
          • 餓了么的 PWA 升級實踐
          • 離線指南
          • Android 中的 WebAPKs [英]
          • Pinterest 的 PWA 實踐 [英]
          • 異步 HTTP Cookies API [英]:賦能Service Worker

          7.2. CSS Houdini

          • 認識 Houdini 與 CSS Paint API [英]
          • 用 Houdini 來拯救 CSS Polyfill [英]

          7.3. Web Components

          • Web Components 基本概念和用法
          • Web Components 指南 [英]
          • Shadow DOM 使用簡介
          • HTMLUnknownElement 與 HTML5 自定義元素的故事

          7.4. 微前端(Micro Frontends)

          • 微前端主頁 [英]
          • 微前端的那些事兒
          • 技術雷達之「微前端」- 將微服務理念擴展到前端開發

          7.5. HTTP/2

          • HTTP/2 幕后原理
          • 全面介紹的 HTTP/2 [英]
          • HTTP/2 主頁:
          • HTTP/2 協議 [英]
          • HPACK: HTTP/2 Header壓縮 [英]

          7.6. WebAssembly

          • WebAssembly 官網
          • WebAssembly 現狀與實戰
          • WebAssembly 系列:
          • 一、生動形象地介紹 WebAssembly
          • 二、JavaScript Just-in-time (JIT) 工作原理
          • 三、編譯器如何生成匯編
          • 四、WebAssembly 工作原理
          • 五、為什么 WebAssembly 更快?
          • 六、WebAssembly 的現在與未來

          8. 業務相關

          在業務中往往還有一些與“業務無關”的場景需求 —— 不論是什么業務幾乎都會遇到;因此,在變與不變中,我們更需要去抽象出這些問題。

          8.1. 數據打點上報

          • 如何精確統計頁面停留時長
          • 揭開JS無埋點技術的神秘面紗

          8.2. 前端監控

          • 前端異常監控解決方案研究
          • 監控平臺前端SDK開發實踐
          • 把前端監控做到極致
          • 前端監控系統探索總結

          8.3. A/B測試

          • Twitter的A/B測試實踐:
          • 一、為什么要測試以及測試的意義
          • 二、技術概述
          • 三、檢測和避免 A/B Test中 bucket不平衡問題
          • 四、A/B Test中使用多個控制的啟示
          • Netflix A/B Test 實驗平臺實踐 [英]
          • 指導方法
          • 實驗中容易遇到的七種問題 [英]
          • 實驗的七個準則 [英]
          • 小流量如何進行AB測試
          • 案例分享
          • 大眾點評AB測試框架Gemini
          • 新浪新聞客戶端AB測試與灰度發布
          • 天貓App A/B測試實踐
          • 工具
          • AB測試樣本數量計算器
          • AB測試結果有效性分析工具

          8.4. “服務端推”

          • 各類“服務器推”技術原理與實例
          • 長連接/websocket/SSE等主流服務器推送技術比較
          • Comet:基于 HTTP 長連接的“服務器推”技術
          • 深入 WebSockets、HTTP/2 SSE [英]
          • WebSocket 應用安全問題分析

          8.5. 動效

          • 動畫設計的12個原則 [英]
          • 貝塞爾曲線掃盲
          • 動畫:從 AE 到 Web
          • 最全最好用的動效落地方法:
          • 基礎知識
          • 落地方式

          9. 不歸類的好文

          開卷有益。

          • Recursion? We don't need no stinking recursion!:如何將一些遞歸改為循環(尾遞歸優化)
          • Turning your web traffic into a Super Computer:通過 Web Worker 和 WebSocket 來將全世界的電腦連接成超級計算機
          • Designing very large (JavaScript) applications:高屋建瓴,適合閱讀與思考

          程序開發過程中,我們始終要謹記的一點就是:程序是寫給人看的,不是寫給機器看的。任何項目開發,都必須要考慮到人員迭代,我們不能讓下一個接手你代碼的人,在看到你寫的代碼時會說出這樣的話,“這個代碼是人寫出來的嗎?可讀性太差了”。因此,我們必須遵循一定的規范,讓代碼的可讀性更強。

          今天,我們就一起來看下前端開發過程所能涉及到的跟HTML有關的規范問題。

          HTML5

          文檔類型

          在HTML文件中,推薦使用支持HTML5特性的文檔聲明,<!DOCTYPE html>。

          命名規范

          首先是在文件的命名上,應當采用駝峰式命名,首字母小寫,后面每個單詞首字母大寫,而且對于具體的文件應當具有語義化,能夠給人一種直觀的感受這個文件的作用是什么。現在前端開發開發過程中都講求模塊化開發,甚至是組件化開發,在文件命名時更應該以模塊名或者組件名來命名。

          例如在寫一個AngularJS應用時,由于會涉及到Controller,Service,Filter等概念,我們會分別建立一個文件,假如這個模塊的名字是庫存管理stockManage,我們可以這樣來命名文件。

          • stockManageCtrl

          • stockChangeService

          • stockChangeFilter

          語義化

          我們所說的語義化指的是使用具有語義化的標簽,在H5中添加了類似于header, nav, article, section, aside, footer等標簽,從單詞的意思上我們也很容易看出標簽的含義。

          我們不推薦使用只有div標簽的頁面,例如

          不推薦使用

          而是應該使用以下這種帶有語義化的標簽。

          推薦使用

          img標簽

          img標簽是網頁用來顯示照片的標簽,在頁面所有標簽中占據的比例非常之高,但是在使用img標簽時也有下面需要注意的點。

          • 給定width和height屬性

          因為瀏覽器在加載圖片的過程中,需要先下載圖片,然后再解析圖片的高度和寬度,如果不給img元素設定高度和寬度,這樣在圖片加載過程中會不斷的計算,重排頁面的布局,在網絡不好的時候就會經常出現元素出現不規律移動的情況。因此給img元素設定width和height屬性是必要的。

          • alt屬性

          img標簽的alt屬性表示的是在圖片無法顯示時,使用文字來代替顯示,它可以用在以下幾個場景中:

          1. 網路延遲太大

          2. src屬性指定路徑出錯

          3. 瀏覽器禁用圖像

          由于其有良好的信息提示效果,并且有助于網頁SEO效果,強烈建議在img標簽中使用alt屬性

          而且很重要的一點是img標簽的引入是需要呈現出與頁面相關的內容,其他情況應該使用CSS樣式實現。例如我們不推薦下面這種情況。

          不推薦

          而推薦使用下面這種情況

          推薦使用

          文件分離

          前端文件主要包括HTML頁面文件,CSS樣式文件和Javascript腳本文件。我們應該讓三者各司其職,在HTML中不應該出現CSS和JS表達式;在JS文件中,不應該出現大量的HTML和CSS代碼。在HTML文檔中應當盡量少的引入CSS和JS文件。為了保證文件的純凈,我們應當遵循下面的原則。

          1. 一個HTML文件應該只引入一個CSS文件

          2. 合理運用JS合并技術(Gulp, Webpack插件),保證引入JS文件不多于兩個

          3. 不使用行內腳本元素(<script>alert('Hello World')</script>)

          4. 不在標簽上使用style內聯樣式

          不要使用style屬性

          腳本加載

          腳本加載在網頁加載過程中是一個很耗性能的過程,如果把JS文件放在head標簽里,它的加載會一直阻塞DOM的解析,造成頁面延遲。

          因此現在講求的是腳本的異步加載過程,我們會使用到async關鍵字,考慮到瀏覽器的兼容性,我們推薦使用下面的方式加載腳本。

          推薦方式

          合理使用ID和錨點

          合理使用ID和錨點可以非常方便的實現當前頁面間的跳轉,現在越來越多的教程網頁由于是單頁面,經常會用到錨點跳轉。

          對錨點知識還不了解的,可以看看我寫的這篇文章《神奇的html錨點,讓你的網頁在內部自由的跳轉》。

          總結

          今天這篇文章主要總結了前端開發過程中的HTML規范問題,相信大家也或多或少遇到過,希望這篇文章能加深大家的認識。


          主站蜘蛛池模板: 琪琪see色原网一区二区| 日韩精品一区在线| 久久精品无码一区二区三区免费 | 国产精品毛片a∨一区二区三区| 91成人爽a毛片一区二区| 精品乱人伦一区二区三区| 在线观看日韩一区| 亚洲综合无码一区二区痴汉| 91精品国产一区| 在线精品国产一区二区| 国产人妖视频一区二区| 久久毛片免费看一区二区三区| 一区二区三区高清视频在线观看| 国内精品视频一区二区三区| 无码中文人妻在线一区二区三区| 亚洲熟妇av一区二区三区下载| 三上悠亚国产精品一区| 国产精品福利区一区二区三区四区 | 国产高清不卡一区二区| 国产综合一区二区在线观看| 中文字幕精品无码一区二区 | 无码人妻av一区二区三区蜜臀| 亚洲狠狠狠一区二区三区| 国产美女一区二区三区| 精品国产鲁一鲁一区二区| 久久久一区二区三区| 一区在线观看视频| 国产精品一区二区久久乐下载| 日本精品一区二区久久久| 亚洲一区二区三区免费| 国产婷婷一区二区三区| 亚洲AV乱码一区二区三区林ゆな | 中文人妻av高清一区二区| 97久久精品午夜一区二区| 久久综合九九亚洲一区| 麻豆AV一区二区三区| 女女同性一区二区三区四区| 国产视频福利一区| 日韩精品无码一区二区视频 | 国产在线视频一区| 亚洲一区中文字幕在线电影网|