jquery-css-mahoro: 新嘗試的集合

April 05, 2016

這篇文章並不是特別用來介紹 jquery-css-mahoro,主要在這次的開源過程中,我嘗試加入了一些之前沒有使用過的工具/流程。

本文將會概述一下這次 jquery-css-mahoro 中的新嘗試有哪些,而日後可能會有一些文章稍微深入介紹本次的新嘗試(也可能沒有,我就是懶),請大家拭目以待。

jquery-css-mahoro

不過還是要先來簡介一下這次的開源小物。

jquery-css-mahoro https://github.com/pc035860/jquery-css-mahoro

是我覺得每次操作 CSS animation 的 class 都很麻煩,進而寫出的小小 jQuery plugin (真心覺得 ngAnimate 超方便)。

它能做的事情就 如 README 裡面所寫

  1. 加上 CSS animation class
  2. CSS animation 開始跑
  3. 移除 CSS animation class

本來我只是把它丟在 某個 gist 裡面,後來發覺這樣要使用還是不太方便,還是需要丟上 NPM;既然要丟上 NPM,不如就找時間來認真的開源一下。

關於命名

現在與 CSS animation 有關的 jQuery plugin 實在太多,大家的名字也都差不多沒什麼識別度,既然這樣我還不如選一個特立獨行一點的,好好地做 SEO 應該還還是會有可見度的啦(吧)。

至於為什麼叫 Mahoro,我想我高中的朋友們比較清楚 w

Read on 

React 碎碎念: 我只是想寫個 CSS

April 02, 2016

是說上次的碎碎念好像有點莫名地在我不知道的地方流傳,我根本沒宣傳那篇文章才對…

總之歡迎關注 React碎碎念 系列文章

碎碎念大部分是個人意見,客觀部分敘述有錯誤歡迎指證。

有一天

這天在 ReactJS.tw 看到了人家轉貼的 新工具介紹文章 — React Storybook,點過去看完之後順道看了一下作者還有寫些什麼文章,於是發現了這篇,也就是本文的主角

State of React and CSS

推薦讀完再繼續看下去。

想想上次發的 React 碎碎念: 艱困的新手之路 也是因為被一些看到的東西點燃了(X)

你原本怎麼寫 CSS?

其實原本有在寫 CSS 到一定程度的人(不管是前端工程師還是網頁設計師),一般會碰到一個轉捩點就是 — 習得 CSS 心法 (WTF)。

寫 CSS 的人,隨著碰過的網頁跟經驗增加,漸漸碰到頁面趨向複雜或是網站越來越巨大,然後 CSS 寫一寫就崩潰了。

於是坊間就有各種拯救你的心法出現,是經過時間淬鍊的成果,你可以選擇 follow 一種,或著結合眾家精隨融會貫通。(或著像我只學了皮毛就一直亂寫)

比較有名的心法這邊列三個:

還有一則很容易不小心就搜尋到的投影片 — 漫談 CSS 架構方法 - 以 OOCSS, SMACSS, BEM 為例

歡迎來到 React 的世界

然而,就是這個然而

在 React 崛起之後,因應它用力的 component 化,帶動了嶄新的 CSS 風潮。上面的 Medium 文章中列出搭配 React 使用的方式有:

  • 使用現成的 CSS framework
  • 寫 (good old) CSS
  • 用別人寫的 React-based UI
  • 用 CSS Modules
  • 在 JS 裡面寫 CSS

上面就 React 出現之後才崛起的其實又大體上可以分成兩類:

  • 在 JS 裡面寫 CSS
  • 用 CSS Modules
Read on 

Blink 系瀏覽器 History API scroll restoration 的 bug

March 03, 2016

Update 2016/04/02 15:30 Opera 36(.0.2130.46) 跟 Chrome 49 同步了,所以這個問題也消失了。此文章正式壽終正寢(?)

Update 2016/03/06 14:00 更新到 Chrome 49(.0.2623.75) 以後這個問題已經修正(bug & commit);而同樣是 Blink 系的 Opera 更新比較慢,在 Opera 35(.0.2066.92) 上還是可以重現問題。


最近寫的東西幾個主要的 view 都跟捲動位置有關,而捲動位置對網站瀏覽者的體驗事關重大。

本文內容針對桌面瀏覽器。

我覺得良好的捲動位置體驗是

  1. 在同頁面重新整理後會回到一樣的位置 (在內容物不變的前提之下)
  2. 承 (1),如果內容物在重新整理後會改變 (ex: Facebook),重新整理後可以乾脆回到頂端
  3. 使用瀏覽器的「上一頁」、「下一頁」進入頁面時會保持之前瀏覽的位置
  4. 曾經瀏覽過的頁面再次透過連結點擊進去後可以重置捲動位置(不需要有 3. 的行為)

上面這幾點基本上完全在現在瀏覽器的掌握之中,然而最近發現的 Blink 系瀏覽器(Chrome、Opera)在使用 History API 時的 scroll restoration 有點奇怪

  • 程式操作後的 scroll 並不會被記錄
  • 預設的捲軸 restoration 不適合一般 single page app

這兩點發生的一個重要前提 - 「在操作之後,使用者沒有再動過捲軸(拉動 scrollbar 或是用滾輪)」

Read on 

webpack chunk 讀出來是空的該怎麼辦

February 12, 2016

總之最近有需求所以用上了 webpack 的 code splitting,就在用爽爽以為世界為我所有的時候,碰到神秘的現象。

環境

為了稍微釐清一下關係,以下的主角分別稱為 A & B

A - 嵌入式的工具,設計為可以嵌入各種網站使用(使用 webpack code splitting) B - 新的 project(使用 webpack),有嵌入 A 做進階使用

這天 B 需要嘗試加入 code splitting,目前只需要分成兩個 chunk,一個 chunk 代表一個 route。

簡單的 code splitting 示意寫法如下:

import dyna from '_util/createDynamicComponent';

const Main = dyna((resolve) => {
  require.ensure([], require => {
    resolve(require('_components/Main').default);
  });
});

照常理來說,webpack 會確保 require.ensure 的 callback 裡面需要執行的東西在讀進來之後才執行;然而,此處的 require('_components/Main') 在實際執行的時候,卻時不時是空的 {}

設身處地的想想,這個 bug 有多難 deeeeeeeeeeeeeeee

webpack magic

在經過多方交叉測試確認不是我程式碼這邊的問題之後,所有的矛頭指向了 webpack。但 webpack 的能力太強、文件寫得不夠詳盡,對我來說 code splitting 這件事就是一個 magic,也因此還真的不知道該怎麼 de webpack 的 bug。

於是我在 google 上搜尋各種可能的 keyword

webpack chunk load failed webpack chunk doesn’t load

然後實際上很莫名的會一直搜到它的文件,以及各種 tutorial 或 opinion 文章,頓時真是覺得這個生態系是不是有什麼問題…

直到我從上面的環境中 identify 了關鍵的可能原因,重新用了這個 keyword

webpack multiple instance

搜尋結果其實看起來還是一樣沒有一矢中的的感覺,不過答案其實默默地藏在第三個結果裡。

Ref: https://github.com/webpack/docs/wiki/configuration#outputjsonpfunction

output.jsonpFunction The JSONP function used by webpack for asnyc loading of chunks. A shorter function may reduce the filesize a bit. Use different identifier, when having multiple webpack instances on a single page.

output.jsonpFunction

有稍微 trace 一下的話,可以知道 webpack 想要載入 chunk 的時候會需要使用這個一個名為 webpackJsonp 的 global function (在 window 底下),而這個設定 output.jsonpFunction 就是用來設定這個 function name 的。

在同一個網頁上面有多個 webpack instance 的時候 (ex: AB 都是 webpack,而且都有做 code split),這個 jsonpFunction 的名字相同會讓兩者其中一方的 chunk loading 陷入錯亂(似乎是編號-based,而編號會混在一起)。

所以最後只需要把 Aoutput.jsonpFunction 改成比較 unique 的就解決了。

TL;DR

條件

  • 同一個頁面會用到兩個以上的 webpack instance
    (一般來說就是兩個從 webpack 面來看沒有相關的 bundle)
  • 有需要做 chunk 載入

需要

  • 透過 output.jsonpFunction 確保兩個 instance 的 jsonp function name 不同
/* file: webpack.config.js */

var config = {
  ...
  output: {
    ...
    jsonpFunction: 'somethingPrettyUniqueJsonp'  // so important
  }
};

後記

是說 multiple webpack instance 需要改 jsonp function name 這種事情這麼重要,也太難找!!!!!!