<?xml version="1.0" encoding="UTF-8"?>
<rss  xmlns:atom="http://www.w3.org/2005/Atom" 
      xmlns:media="http://search.yahoo.com/mrss/" 
      xmlns:content="http://purl.org/rss/1.0/modules/content/" 
      xmlns:dc="http://purl.org/dc/elements/1.1/" 
      version="2.0">
<channel>
<title>Byte-Sized Blog</title>
<link>https://hanjianwei.github.io/</link>
<atom:link href="https://hanjianwei.github.io/index.xml" rel="self" type="application/rss+xml"/>
<description></description>
<generator>quarto-1.7.6</generator>
<lastBuildDate>Wed, 18 Mar 2020 03:04:19 GMT</lastBuildDate>
<item>
  <title>40%键盘YDPM40</title>
  <link>https://hanjianwei.github.io/posts/2020/03/18/ydpm40-keyboard/</link>
  <description><![CDATA[ 





<p>最近看到有人晒的<a href="https://ergodox-ez.com/pages/planck">Planck EZ</a>，对40%键盘非常心动，不过Planck EZ的价格还是太高了，于是在咸鱼上入了一把<a href="https://ydkb.io/help/#/keyboards/ydpm40">YDPM40</a>。YDPM40是YANG设计的，分为YDP40和YDM40两种布局，前者是类似于Planck的直排，而后者更接近于一般键盘的斜排。我买的这把是YDM40，共44个键，非常适合极简主义者以及囊中羞涩（毕竟需要的轴比较少）、喜欢折腾的人。</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://hanjianwei.github.io/posts/2020/03/18/ydpm40-keyboard/ydpm40.jpg" class="img-fluid figure-img"></p>
<figcaption>YDPM40</figcaption>
</figure>
</div>
<p>对于40%键盘，简洁固然有了，但是也给使用者一个难题：如何保证打字体验？答案是「层」。层其实并非一个很新的概念，考虑一下我们使用的键盘，同一个字母的大小写都是由一个键来实现的，输入小写字母的时候直接按该键，输入大写字母的时候按住<code>Shift</code>再按对应的键。这其实相当于把键盘分为两层：大写字母和小写字母，其中小写字母是默认层，按住<code>Shift</code>瞬时切换到大写字母层。大部分键盘还有一个<code>Caps Lock</code>键，按一下就直接打开了大写字母层。</p>
<p>YDMP40基于hasu写的<a href="https://geekhack.org/index.php?topic=41989.0">TMK</a>固件，该固件的初衷是给HHKB加上可编程接口（以及蓝牙支持），其中<a href="https://github.com/tmk/tmk_keyboard/wiki/Keymap">对层的支持更加强大</a>，为客制化键盘提供了非常强大的工具。TMK层的示意图如下：</p>
<pre><code>Keymap: 32 Layers                   Layer: Keycode matrix
-----------------                   ---------------------
stack of layers                     array_of_keycode[row][column]
       ____________ precedence               _______________________
      /           / | high                  / ESC / F1  / F2  / F3   ....
  31 /___________// |                      /-----/-----/-----/-----
  30 /___________// |                     / TAB /  Q  /  W  /  E   ....
  29 /___________/  |                    /-----/-----/-----/-----
   :   _:_:_:_:_:__ |               :   /LCtrl/  A  /  S  /  D   ....
   :  / : : : : : / |               :  /  :     :     :     :
   2 /___________// |               2 `--------------------------
   1 /___________// |               1 `--------------------------
   0 /___________/  V low           0 `--------------------------</code></pre>
<p>TMK最多支持32层，YDMP40支持8层。每一层都有一个开关状态，也有对应的优先级；对于键盘上的每个键，我们可以设置它在每一层的值：一般键值、透明或者禁用。在我们按下每个键时，首先对激活的层按照优先级从高到低进行查询，如果有键值或者是禁用，则停止；如果遇到透明值，则继续到低优先级的层查询。通过这样一种简单的机制，就可以在同一个键上叠加不同的值，然后根据切换层的开关状态来实现多种输入效果，对于小键盘而言实在是非常强大的工具。YANG提供了一个<a href="http://ydkb.io/">网站</a>来进行各个层的设置，设置完之后可以载固件，用提供的工具来刷固件。</p>
<p>在定义布局时，我想尽量保持布局和其他键盘一致，同时使得常用的键都能够在默认层上，所以复用了很多的键（比如单按左空格就是空格，长按或与其他键组合就是开启第7层），这是我的键盘布局：</p>
<div class="quarto-figure quarto-figure-center">
<figure class="figure">
<p><img src="https://hanjianwei.github.io/posts/2020/03/18/ydpm40-keyboard/layers.jpg" class="img-fluid figure-img"></p>
<figcaption>My Layers</figcaption>
</figure>
</div>
<p>我把次常用的数字键以及符号设置到了第7层，这是为了使用YDMP里面的一个「特殊功能」，也就是「单按↑为向上，长按为按住R Shift并瞬间开启第七层」，这样就可以按住上箭头直接输入数字键上面的符号了。</p>
<p>总体来说，对这把键盘还是比较满意的，虽然键比较少，但是通过层和键的复用，可以最大程度满足日常使用。此外，由于键盘比较小，能够使大部分的键都在手的范围内，不用大范围的移动也算一种优势。如果说缺点，把常用键都塞到默认层还是有点勉强，如果能多一列可能会好很多。</p>
<section id="更新" class="level2">
<h2 class="anchored" data-anchor-id="更新">3.24更新</h2>
<p>经过几天的使用，发现<code>:;</code>键按起来不太方便，但是这两个符号使用的还挺多的: <code>:</code>在vim里面用的很多，而<code>;</code>在微软双拼里面代表<code>ing</code>。我对布局进行了一些微调: 在第7层将右空格设置为<code>:;</code>，同时在<a href="https://karabiner-elements.pqrs.org/">Karabiner Elements</a>里面针对YDM40做了如下设定：</p>
<ol type="1">
<li>如果是英文输入法，交换冒号<code>:</code>和分号<code>;</code>，这样我就可以同时按住两个空格键输入vim的命令了。</li>
<li>如果是双拼输入法，交换回车和分号，这样就可以按回车当成<code>ing</code>，同时按住两个空格回车了。</li>
</ol>
<p>Karabiner里面支持针对设备和输入法设置，还是比较方便的，我的karabiner的设置如下， 点击<a href="karabiner://karabiner/assets/complex_modifications/import?url=ydpm40.json">链 接</a> 即可添加到karabiner elements的complex modifications中：</p>
<div class="code-with-filename">
<div class="code-with-filename-file">
<pre><strong>ydmp40.json</strong></pre>
</div>
<div class="sourceCode" id="cb2" data-filename="ydmp40.json" style="background: #f1f3f5;"><pre class="sourceCode json code-with-copy"><code class="sourceCode json"><span id="cb2-1"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-2">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"title"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"YDPM40 key settings"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-3">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"rules"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-4">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-5">      <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"description"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Exchange semicolon and colon"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-6">      <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"manipulators"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-7">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-8">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"conditions"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-9">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-10">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"input_sources"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-11">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-12">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"input_source_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"com</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.apple</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.keylayout</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.ABC"</span></span>
<span id="cb2-13">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-14">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-15">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"input_source_if"</span></span>
<span id="cb2-16">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-17">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-18">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"device_if"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-19">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"identifiers"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-20">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-21">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"vendor_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">65261</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-22">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"product_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">576</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-23">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"description"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"YDM40"</span></span>
<span id="cb2-24">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-25">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-26">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-27">          <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-28">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"from"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-29">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"key_code"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"semicolon"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-30">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiers"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-31">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"optional"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-32">                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"caps_lock"</span></span>
<span id="cb2-33">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-34">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-35">          <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-36">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"to"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-37">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-38">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"key_code"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"semicolon"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-39">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiers"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-40">                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"left_shift"</span></span>
<span id="cb2-41">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-42">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-43">          <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-44">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"basic"</span></span>
<span id="cb2-45">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-46">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-47">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"conditions"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-48">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-49">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"input_sources"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-50">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-51">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"input_source_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"com</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.apple</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.keylayout</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.ABC"</span></span>
<span id="cb2-52">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-53">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-54">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"input_source_if"</span></span>
<span id="cb2-55">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb2-56">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-57">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"device_if"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-58">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"identifiers"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-59">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-60">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"vendor_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">65261</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-61">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"product_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">576</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-62">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"description"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"YDM40"</span></span>
<span id="cb2-63">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-64">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-65">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-66">          <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-67">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"from"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-68">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"key_code"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"semicolon"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-69">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiers"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-70">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"mandatory"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-71">                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"shift"</span></span>
<span id="cb2-72">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-73">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"optional"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-74">                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"caps_lock"</span></span>
<span id="cb2-75">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-76">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-77">          <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-78">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"to"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-79">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-80">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"key_code"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"semicolon"</span></span>
<span id="cb2-81">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-82">          <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-83">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"basic"</span></span>
<span id="cb2-84">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-85">      <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-86">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-87">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-88">      <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"description"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"Exchange return and semicolon"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-89">      <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"manipulators"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-90">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-91">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"conditions"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-92">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-93">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"input_sources"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-94">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-95">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"input_source_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"com</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.apple</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.inputmethod</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.SCIM</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.Shuangpin"</span></span>
<span id="cb2-96">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-97">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-98">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"input_source_if"</span></span>
<span id="cb2-99">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span> </span>
<span id="cb2-100">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-101">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"device_if"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-102">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"identifiers"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-103">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-104">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"vendor_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">65261</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-105">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"product_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">576</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-106">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"description"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"YDM40"</span></span>
<span id="cb2-107">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-108">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-109">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-110">          <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-111">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"from"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-112">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"key_code"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"semicolon"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-113">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiers"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-114">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"optional"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-115">                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"caps_lock"</span></span>
<span id="cb2-116">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-117">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-118">          <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-119">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"to"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-120">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-121">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"key_code"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"return_or_enter"</span></span>
<span id="cb2-122">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-123">          <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-124">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"basic"</span></span>
<span id="cb2-125">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-126">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-127">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"conditions"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-128">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-129">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"input_sources"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-130">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-131">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"input_source_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"com</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.apple</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.inputmethod</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.SCIM</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">\\</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">.Shuangpin"</span></span>
<span id="cb2-132">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-133">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-134">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"input_source_if"</span></span>
<span id="cb2-135">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-136">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-137">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"device_if"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-138">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"identifiers"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-139">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-140">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"vendor_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">65261</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-141">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"product_id"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">576</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-142">                  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"description"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"YDM40"</span></span>
<span id="cb2-143">                <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-144">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-145">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-146">          <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-147">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"from"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-148">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"key_code"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"return_or_enter"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-149">            <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"modifiers"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-150">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"optional"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-151">                <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"caps_lock"</span></span>
<span id="cb2-152">              <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-153">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-154">          <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">},</span></span>
<span id="cb2-155">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"to"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">[</span></span>
<span id="cb2-156">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-157">              <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"key_code"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"semicolon"</span></span>
<span id="cb2-158">            <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-159">          <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-160">          <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">"type"</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"basic"</span></span>
<span id="cb2-161">        <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-162">      <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-163">    <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span>
<span id="cb2-164">  <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">]</span></span>
<span id="cb2-165"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
</div>


</section>

 ]]></description>
  <category>Hardware</category>
  <guid>https://hanjianwei.github.io/posts/2020/03/18/ydpm40-keyboard/</guid>
  <pubDate>Wed, 18 Mar 2020 03:04:19 GMT</pubDate>
</item>
<item>
  <title>网件WNDR4300上安装配置OpenWrt</title>
  <link>https://hanjianwei.github.io/posts/2015/12/02/openwrt-setup/</link>
  <description><![CDATA[ 





<p>WNDR4300是对OpenWrt支持比较好的一款路由器：其内存和闪存都是128M，有比较好的ROM支持，是一个比较适合折腾的路由器。</p>
<section id="openwrt的安装配置" class="level3">
<h3 class="anchored" data-anchor-id="openwrt的安装配置">OpenWrt的安装、配置</h3>
<p>首先，下载WNDR4300的固件，OpenWrt的<a href="https://downloads.openwrt.org">下载页面</a>列出了不同版本的的固件，一般来说下载最新的release即可。 比如当前支持WNDR4300的最新固件是<a href="https://downloads.openwrt.org/chaos_calmer/15.05/ar71xx/nand/openwrt-15.05-ar71xx-nand-wndr4300-ubi-factory.img">Chaos Calmer 15.05</a>。在下载的时候需要注意，如果是第一次刷机，要下载factory固件；如果以前刷过OpenWrt，下载sysupgrade。</p>
<p>然后，进入路由器的web界面，找到「固件升级」，选择下载的包确定。重启后，路由器的系统就变成OpenWrt了。需要注意的是，重启后默认Wifi没有开启，按一下路由器上的Wifi开关即可。在电脑上，连上OpenWrt这个热点，浏览器打开<code>192.168.1.1</code>登录，用户名为root，没有密码。进入系统后，先进入「System → Administration」修改密码、添加SSH公钥等。</p>
<p>在web页面选择「Network → Interfaces」，对WAN口进行配置。然后进入「Network → Wifi」，设置SSID和Wifi密码。</p>
</section>
<section id="shadowsocks" class="level2">
<h2 class="anchored" data-anchor-id="shadowsocks">Shadowsocks</h2>
<p>首先，在路由器上安装<a href="https://shadowsocks.org">shadowsocks</a>的客户端：</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> opkg install http://openwrt-dist.sourceforge.net/releases/ar71xx/packages/shadowsocks-libev_2.4.1-1_ar71xx.ipk</span></code></pre></div>
<p>安装时到shadowsock的<a href="http://openwrt-dist.sourceforge.net/releases/ar71xx/packages/">下载页面</a>确定软件的具体版本。如果你空间有限，也可以装<code>polarssl</code>版本。</p>
<p>编辑<code>/etc/shadowsock.json</code>，填上你shadowsock服务器的信息。</p>
<p>然后设置shadowsock自动启动：</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> /etc/init.d/shadowsocks enable</span>
<span id="cb2-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> /etc/init.d/shadowsocks start</span></code></pre></div>
<p>你可以将自己系统的SOCKS Proxy设置为<code>192.168.1.1:1080</code>，测试下shadowsocks是否工作正常。如果工作正常，将<code>/etc/init.d/shadowsocks</code>文件中的<code>ss-local</code>换成<code>ss-redir</code>并重启shadowsocks，表示我们要用shadowsocks进行转发。</p>
<section id="dsn服务器设置" class="level3">
<h3 class="anchored" data-anchor-id="dsn服务器设置">DSN服务器设置</h3>
<p>为了防止DNS污染，利用dnsmasq将<a href="https://github.com/gfwlist/gfwlist">gfwlist</a>中的域名用OpenDNS解析。OpenWrt自带的dnsmasq功能是有限制的，首先安装上完全版的dnsmasq，并安装ipset包:</p>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> opkg remove dnsmasq <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&amp;&amp;</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">opkg</span> install dnsmasq-full</span>
<span id="cb3-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> opkg install ipset</span></code></pre></div>
<p>我们创建一个名为gfw的ipset，并设置所有ipset中的IP都通过shadowsocks转发。</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ipset create gfw hash:ip</span>
<span id="cb4-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> iptables <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-t</span> nat <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-A</span> PREROUTING <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-p</span> tcp <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-m</span> set <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--match-set</span> gfw dst <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-j</span> REDIRECT <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--to-port</span> 1079</span></code></pre></div>
<p>为了防止路由器重启时规则丢失，可以将上述规则写到<code>/etc/firewall.user</code>文件中。</p>
<p>然后利用<a href="https://github.com/cokebar/gfwlist2dnsmasq">gfwlist2dnsmasq</a>生成<code>dnsmasq_list.conf</code>文件，记得运行命令之前将<code>gfwlist2dnsmasq.py</code>中的<code>mydnsip</code>改成208.67.220.220，<code>mydnsport</code>改成443，<code>ipsetname</code>改成gfw。</p>
<div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> python gfwlist2dnsmasq.py</span></code></pre></div>
<p>修改dnsmasq的配置文件<code>/etc/dnsmasq.conf</code>，在最后加上一句：</p>
<div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode ini code-with-copy"><code class="sourceCode ini"><span id="cb6-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">conf-dir</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">/etc/dnsmasq.d</span></span></code></pre></div>
<p>最后将生成的<code>dnsmasq_list.conf</code>拷贝到<code>/etc/dnsmasq.d</code>中，重启dnsmasq：</p>
<div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> /etc/init.d/dnsmasq restart</span></code></pre></div>
<p>搞定！</p>


</section>
</section>

 ]]></description>
  <category>Networking</category>
  <guid>https://hanjianwei.github.io/posts/2015/12/02/openwrt-setup/</guid>
  <pubDate>Wed, 02 Dec 2015 12:04:00 GMT</pubDate>
</item>
<item>
  <title>SmartOS折腾笔记</title>
  <link>https://hanjianwei.github.io/posts/2015/07/08/smartos-nas/</link>
  <description><![CDATA[ 





<p>前段时间入手了一台<a href="http://www8.hp.com/us/en/products/proliant-servers/product-detail.html?oid=5379860">Gen8</a>，准备用做家里文件、媒体服务器。看了<a href="https://www.vmware.com/products/vsphere-hypervisor">EXSi</a>、<a href="http://www.freenas.org">FreeNAS</a>、<a href="http://www.nas4free.org">NAS4Free</a>、<a href="https://www.proxmox.com/en/">Proxmox</a>等方案后，觉得还是<a href="https://smartos.org">SmartOS</a>最好。它支持<a href="https://en.wikipedia.org/wiki/ZFS">ZFS</a>，能够更好管理数据、保证数据有效性；此外，它支持<a href="https://en.wikipedia.org/wiki/Kernel-based_Virtual_Machine">kvm</a>虚拟化技术，能够虚拟常见的操作系统，满足各种软件需求；它还支持类似Docker的<a href="https://en.wikipedia.org/wiki/Solaris_Containers#Branded_zones">Zones</a>容器技术，比kvm更为高效。</p>
<section id="安装配置" class="level3">
<h3 class="anchored" data-anchor-id="安装配置">安装配置</h3>
<p>SmartOS可以装在一个U盘里面。这样的好处很多，比如增加了系统的安全性和稳定性，可用磁盘空间也大了，系统升级也很简单——更新一下U盘就行了。我用了一个16G的U盘，按照<a href="https://wiki.smartos.org/display/DOC/Creating+a+SmartOS+Bootable+USB+Key">官方的教程</a>下载镜像、创建可启动U盘，然后从U盘启动就可以了。</p>
<p>SmartOS使用了<a href="https://wiki.smartos.org/display/DOC/Zones">zones</a>技术，U盘启动后进入一个全局的zone(Global Zone)，负责管理其它的zone。一个zone就是一个虚拟化的实例，SmartOS创建的每个虚拟机都是跑在一个单独的zone里面。</p>
<p>SmartOS使用了ZFS文件系统，所有虚拟机的zone都是存放在一个叫<code>zones</code>的zpool中。第一次启动时，除了让你配置网络，还会要求你创建<code>zones</code>。我有4块3T的硬盘，1块256G的SSD，在启动时选择4块硬盘组成一个<a href="https://blogs.oracle.com/ahl/entry/what_is_raid_z">raidz</a>来作为zones池。在我的机器上，4块硬盘分别是c1t0d0, c1t1d0, c1t2d0和c1t3d0。</p>
<p>为了取得更好的性能，用<a href="http://docs.oracle.com/cd/E23824_01/html/821-1459/disksprep-10.html">format</a>将SSD（c1t4d0）分为32G和224G两个分区，分别作为ZIL(log)和L2ARC(cache):</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># zpool add zones log c1t4d0s0</span></span>
<span id="cb1-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># zpool add zones cache c1t4d0s1</span></span></code></pre></div>
<p>配置完之后磁盘的信息如下：</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># zpool status</span></span>
<span id="cb2-2">  <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">pool:</span> zones</span>
<span id="cb2-3"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">state:</span> ONLINE</span>
<span id="cb2-4">  <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">scan:</span> none requested</span>
<span id="cb2-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">config:</span></span>
<span id="cb2-6"></span>
<span id="cb2-7">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">NAME</span>        STATE     READ WRITE CKSUM</span>
<span id="cb2-8">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">zones</span>       ONLINE       0     0     0</span>
<span id="cb2-9">          <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">raidz1-0</span>  ONLINE       0     0     0</span>
<span id="cb2-10">            <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">c1t0d0</span>  ONLINE       0     0     0</span>
<span id="cb2-11">            <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">c1t1d0</span>  ONLINE       0     0     0</span>
<span id="cb2-12">            <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">c1t2d0</span>  ONLINE       0     0     0</span>
<span id="cb2-13">            <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">c1t3d0</span>  ONLINE       0     0     0</span>
<span id="cb2-14">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">logs</span></span>
<span id="cb2-15">          <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">c1t4d0s0</span>  ONLINE       0     0     0</span>
<span id="cb2-16">        <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">cache</span></span>
<span id="cb2-17">          <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">c1t4d0s1</span>  ONLINE       0     0     0</span>
<span id="cb2-18"></span>
<span id="cb2-19"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">errors:</span> No known data errors</span></code></pre></div>
<p>如果上述步骤搞错了，可以参照<a href="https://wiki.smartos.org/display/DOC/SmartOS+Clean+Re-install">官方的步骤</a>重装。很不幸的是，我安装官方的步骤选择Grub第2项（noinstall）几乎每次都会死机，如果你遇到和我一样的情况，也可以在启动时出现Grub界面的时候，在第1项按<code>e</code>，然后在最后加上<code>destroy_zpools=true</code>的选项，这样启动后就会删除所有的zpool，然后就可以重新配置了。（注意：磁盘上已经有数据的慎用！）</p>
</section>
<section id="创建虚拟机" class="level3">
<h3 class="anchored" data-anchor-id="创建虚拟机">创建虚拟机</h3>
<p>U盘启动的SmartOS是一个只读系统，你所能做的事情非常有限。不过SmartOS就是为虚拟化而生的，它支持zones和kvm两种虚拟化技术，前者类似容器技术，具有很好的性能，但支持的OS较少；后者性能不如前者，但能支持大部分常见的OS。</p>
<p><code>imgadm</code>和<code>vmadm</code>是管理虚拟机的两个常用命令，前者主要用来管理镜像，而后者用来管理虚拟机。你可以通过<code>imgadm avail</code>来查看已有的虚拟机镜像，用<code>vmadm create</code>来根据镜像创建虚拟机。</p>
<p>此外，我希望数据能够单独存储，即使虚拟机坏掉或者删除数据仍然存在，因此专门建立一个数据存储的dataset：</p>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># zfs create zones/datastore</span></span></code></pre></div>
<section id="kvm虚拟机" class="level4">
<h4 class="anchored" data-anchor-id="kvm虚拟机">kvm虚拟机</h4>
<p>kvm是从linux移植过来的技术，能支持大部分常见的操作系统，在创建kvm虚拟机之前首先要创建或下载相应的镜像。Joyent已经提供了很多常见的镜像，如果我想装一个debian 8，可以首先进行搜索：</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># imgadm avail | grep debian-8</span></span>
<span id="cb4-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">ca291f66-048c-11e5-98b3-c3f2a972a4cc</span>  debian-8                20150527    linux    2015-05-27T16:24:03Z</span>
<span id="cb4-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">2f56d126-20d0-11e5-9e5b-5f3ef6688aba</span>  debian-8                20150702    linux    2015-07-02T15:37:02Z</span></code></pre></div>
<p>然后可以选择需要的镜像进行下载：</p>
<div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># imgadm import 2f56d126-20d0-11e5-9e5b-5f3ef6688aba</span></span></code></pre></div>
<p>创建虚拟机时，首先需要创建一个JSON格式的虚拟机描述文件，下面是debian 8的描述文件，主要是网络设置以及镜像设置：</p>
<div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb6-1">{</span>
<span id="cb6-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"brand"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kvm"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"alias"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"debian"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-4">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hostname"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"debian"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"resolvers"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb6-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-7">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"114.114.114.114"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-8">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"8.8.8.8"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"8.8.4.4"</span></span>
<span id="cb6-10">  ]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-11">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ram"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2048"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-12">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"vcpus"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-13">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nics"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb6-14">    {</span>
<span id="cb6-15">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nic_tag"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"admin"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-16">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ip"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.102"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-17">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"netmask"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"255.255.255.0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-18">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gateway"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-19">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"model"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"virtio"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-20">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"primary"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span></span>
<span id="cb6-21">    }</span>
<span id="cb6-22">  ]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-23">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"disks"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb6-24">    {</span>
<span id="cb6-25">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"image_uuid"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2f56d126-20d0-11e5-9e5b-5f3ef6688aba"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-26">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"boot"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb6-27">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"model"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"virtio"</span></span>
<span id="cb6-28">    }</span>
<span id="cb6-29">  ]</span>
<span id="cb6-30">}</span></code></pre></div>
<p>具体的可用选项可以查看<code>vmadm</code>的<a href="https://github.com/joyent/smartos-live/blob/master/src/vm/man/vmadm.1m.md">文档</a>以及SmartOS的<a href="https://wiki.smartos.org/display/DOC/How+to+create+a+KVM+VM+%28+Hypervisor+virtualized+machine+%29+in+SmartOS">wiki</a>。</p>
<p>将文件存为<code>debian8.json</code>，然后就可以通过<code>vmadm</code>创建镜像：</p>
<div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># vmadm create -f debian8.json </span></span>
<span id="cb7-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Successfully</span> created VM b94d3a92-4a3b-4fae-baca-e53c726be924</span></code></pre></div>
<p>可以通过<code>vmadm list</code>来查看当前虚拟机的状态。创建好的虚拟机可以通过VNC登录，首先要查看虚拟机的VNC信息，然后通过ip和端口进行登录：</p>
<div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb8-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># vmadm info b94d3a92-4a3b-4fae-baca-e53c726be924 vnc</span></span>
<span id="cb8-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">{</span></span>
<span id="cb8-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"vnc"</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb8-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"host"</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.100"</span>,</span>
<span id="cb8-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"port"</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">:</span> 57869,</span>
<span id="cb8-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"display"</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">:</span> 51969</span>
<span id="cb8-7">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">}</span></span>
<span id="cb8-8"><span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>我们希望在虚拟机中访问<code>datastore</code>，并将重要的数据存在其中，这样即使虚拟机挂掉也不影响数据的访问。可以通过<a href="https://wiki.smartos.org/display/DOC/Configuring+NFS+in+SmartOS">NFS</a>来进行文件恭喜。首先将<code>datastore</code>共享：</p>
<div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb9-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># zfs set sharenfs='rw=@192.168.1.0/24,root=192.168.1.102' zones/datastore</span></span></code></pre></div>
<p>在debian里面安装nfs相关的包并将datastore挂载过去：</p>
<div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb10-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># apt-get update &amp;&amp; apt-get install nfs-common</span></span>
<span id="cb10-2"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># mkdir -p /mnt/datastore &amp;&amp; mount -o rw,async,hard,intr 192.168.1.100:/zones/datastore /mnt/datastore</span></span></code></pre></div>
<p>在debian虚拟机中就可以将常用数据放在/mnt/datastore中了。</p>
</section>
<section id="zone" class="level4">
<h4 class="anchored" data-anchor-id="zone">zone</h4>
<p>Zone是一种更高效的虚拟化技术，但是它适用的OS也比较有限。比如你如果想玩玩SmartOS，那用Global Zone的系统可能不是一个很好的选择，因为它是只读的，而且缺少包管理等工具。我们可以用zone虚拟一个SmartOS，你可以用<code>imgadm</code>搜索并下载<code>base64</code>镜像，并通过下面的JSON文件来创建虚拟机：</p>
<div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb11-1">{</span>
<span id="cb11-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"brand"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"joyent"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"image_uuid"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"62f148f8-6e84-11e4-82c5-efca60348b9f"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-4">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"alias"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"smartos"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hostname"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"smartos"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-6">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"max_physical_memory"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2048</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-7">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"quota"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">20</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-8">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"resolvers"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"114.114.114.114"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"8.8.8.8"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"8.8.4.4"</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-9">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nics"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb11-10">    {</span>
<span id="cb11-11">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nic_tag"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"admin"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-12">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ip"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.101"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-13">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"netmask"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"255.255.255.0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb11-14">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gateway"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.1"</span></span>
<span id="cb11-15">    }</span>
<span id="cb11-16">  ]</span>
<span id="cb11-17">}</span></code></pre></div>
<p>然后，用<code>vmadm</code>来创建虚拟机。和kvm不同的是，这种方式创建的虚拟机不能用VNC登录，但是可以用zlogin来登录：</p>
<div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb12-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># vmadm create -f smartos.json </span></span>
<span id="cb12-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Successfully</span> created VM 0b3c7b3b-9f19-4d26-ab22-a8b10a9add25</span>
<span id="cb12-3"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># zlogin 0b3c7b3b-9f19-4d26-ab22-a8b10a9add25 </span></span>
<span id="cb12-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">[Connected</span> to zone <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'0b3c7b3b-9f19-4d26-ab22-a8b10a9add25'</span> pts/2]</span>
<span id="cb12-5">   <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">__</span>        .                   .</span>
<span id="cb12-6"> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">_</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span>  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">_</span>      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">.-.</span> .  . .-. :--. <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span></span>
<span id="cb12-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">_</span>    _<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span>     <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;|</span>   <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">||</span>  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">.-</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">' |  | |</span></span>
<span id="cb12-8"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">  |__|   `--'</span>  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">-</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">' `;-| `-'</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'  '</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'</span></span>
<span id="cb12-9"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                   /  ; Instance (base64 14.3.0)</span></span>
<span id="cb12-10"><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">                   `-'</span>  http://wiki.joyent.com/jpc2/Base+Instance</span></code></pre></div>
<p>Zone不只是支持SmartOS，它还支持<a href="https://wiki.smartos.org/display/DOC/LX+Branded+Zones">LX Branded Zones</a>，允许你在zone里面直接运行linux。<code>imgadm avail</code>中列出的镜像中以<code>lx-</code>开头的支持LX Branded Zones。此外，使用这种方法创建虚拟机时，不必用NFS来共享数据，可以直接通过<code>filesystems</code>字段来指定目录映射。下面是一个<code>lx-ubuntu-14.04</code>的例子：</p>
<div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb13-1">{</span>
<span id="cb13-2">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"brand"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lx"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-3">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"alias"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ubuntu1404"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-4">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kernel_version"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"3.13.0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-5">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"max_physical_memory"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">2048</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-6">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"image_uuid"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"a21a64a0-0809-11e5-a64f-ff80e8e8086f"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-7">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"resolvers"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"114.114.114.114"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"8.8.8.8"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"8.8.4.4"</span>]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-8">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nics"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb13-9">    {</span>
<span id="cb13-10">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"nic_tag"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"admin"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-11">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ip"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.103"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-12">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"netmask"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"255.255.255.0"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-13">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"gateway"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.1.1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-14">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"primary"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">true</span></span>
<span id="cb13-15">    }</span>
<span id="cb13-16">  ]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-17">  <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"filesystems"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb13-18">    {</span>
<span id="cb13-19">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"type"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"lofs"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-20">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"source"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"zones/datastore"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb13-21">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"target"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/mnt/datastore"</span></span>
<span id="cb13-22">    }</span>
<span id="cb13-23">  ]</span>
<span id="cb13-24">}</span></code></pre></div>
<p>可以看到我们直接将Global Zone的<code>zones/datastore</code>映射到虚拟机的<code>/mnt/datastore</code>。然后就可以通过zlogin进行登录，设置好ssh后也可以通过ssh远程登录。</p>
<p>SmartOS确实是一个很适合NAS的系统，还有更多的特性有待发掘。</p>


</section>
</section>

 ]]></description>
  <category>DevOps</category>
  <guid>https://hanjianwei.github.io/posts/2015/07/08/smartos-nas/</guid>
  <pubDate>Wed, 08 Jul 2015 12:04:00 GMT</pubDate>
</item>
<item>
  <title>备份Mac AppStore中安装的应用</title>
  <link>https://hanjianwei.github.io/posts/2015/02/16/backup-mac-appstore-apps/</link>
  <description><![CDATA[ 





<p>在Mac中安装软件并不像Linux那么方便，它没有一个统一的软件管理器来处理大部分的情况。我同时用了<a href="http://brew.sh/">Homebrew</a>、<a href="http://caskroom.io/">Homebrew Cask</a>和Mac AppStore来安装不同的软件。前者主要用于安装命令行程序，而后两者用于安装GUI程序。有些软件在Cask和AppStore中都有，以前我都是倾向于使用Cask，主要是便于备份，重新安装时比较方便。但是，Cask也有它自己的缺点，比如软件升级做得不好。最近试着去备份AppStore中的程序，希望能够自动化AppStore中程序的安装。</p>
<p>备份程序主要用了系统的<code>mdfind</code>和<code>mdls</code>命令:</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">mdfind</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"kMDItemAppStoreHasReceipt=1"</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">read</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-r</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">app</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb1-2">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">echo</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$app</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">\n</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">mdls</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-name</span> kMDItemAppStoreAdamID <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-raw</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$app)</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb1-3"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">done</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> Applications.txt</span></code></pre></div>
<p>App的程序名及其ID会被写入到<code>Applications.txt</code>中。</p>
<p>恢复安装时，读入<code>Applications.txt</code>，逐个读入应用，并打开AppStore进行安装：</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">while</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">read</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-r</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">app</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span></span>
<span id="cb2-2">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">read</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-r</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">appid</span></span>
<span id="cb2-3"></span>
<span id="cb2-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[[</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">!</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">-e</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$app</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]];</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">then</span></span>
<span id="cb2-5">    <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">open</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-W</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"macappstore://itunes.apple.com/cn/app/id</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$appid</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"</span></span>
<span id="cb2-6">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fi</span></span>
<span id="cb2-7"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">done</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"./Applications.txt"</span></span></code></pre></div>
<p>也算一种半人肉的安装方式吧。</p>



 ]]></description>
  <category>DevOps</category>
  <guid>https://hanjianwei.github.io/posts/2015/02/16/backup-mac-appstore-apps/</guid>
  <pubDate>Mon, 16 Feb 2015 12:04:00 GMT</pubDate>
</item>
<item>
  <title>Nix: 纯函数式包管理器</title>
  <link>https://hanjianwei.github.io/posts/2014/09/21/nix-the-purely-functional-package-manager/</link>
  <description><![CDATA[ 





<p><a href="http://nixos.org/nix/">Nix</a>是一个Linux/Unix下的<a href="https://en.wikipedia.org/wiki/Package_management_system">包管理器</a>，它支持原子升级和回滚、能够同时安装同一个包的多个版本、支持多用户，能够更加简单地搭建开发、构建环境。它最大的卖点在于 <em>函数式</em> 的管理方式：把软件包作为函数式语言的值，这些值由没有副作用的函数构建，一旦构建完就不再改变，这意味着你的软件运行环境一旦构建就不会改变——这对于可重现的开发而言非常重要。</p>
<section id="安装" class="level3">
<h3 class="anchored" data-anchor-id="安装">安装</h3>
<p>如果你想充分体验Nix的强大功能，可以安装<a href="http://nixos.org">NixOS</a>，它是一个构建于Nix之上的Linux发型版。</p>
<p>如果你不想装一个新的系统，或者像我一样主要用Mac OSX工作，也可以只安装Nix。最简单的方式就是在Terminal里面执行如下命令：</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> bash <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">curl</span> https://nixos.org/nix/install<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
<p>然后把下面这段脚本加入到你的shell启动文件中(<code>~/.zshrc</code>、<code>~/.bashrc</code>等)：</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">[</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">-e</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$HOME</span>/.nix-profile/etc/profile.d/nix.sh <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">]</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">then</span></span>
<span id="cb2-2">  <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">source</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$HOME</span>/.nix-profile/etc/profile.d/nix.sh<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">;</span></span>
<span id="cb2-3"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">fi</span></span></code></pre></div>
<p>然后就可以查看有什么可用的包：</p>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"></span>
<span id="cb3-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-qa</span></span></code></pre></div>
<p>安装一个包：</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-i</span> hello</span></code></pre></div>
<p>卸载一个包：</p>
<div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-e</span> hello</span></code></pre></div>
<p>升级所有的包：</p>
<div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb6-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-channel <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--update</span> nixpkgs</span>
<span id="cb6-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-u</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'*'</span></span></code></pre></div>
<p>回滚上一步操作：</p>
<div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--rollback</span></span></code></pre></div>
<p>垃圾回收不用的包：</p>
<div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb8-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-collect-garbage <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-d</span></span></code></pre></div>
</section>
<section id="包管理" class="level3">
<h3 class="anchored" data-anchor-id="包管理">包管理</h3>
<p>安装Nix时主要创建了两个目录：<code>/nix</code>和<code>$HOME/.nix-profile</code>。我们来看看安装的包到底是如何组织的，比如当前有一个包<code>hello</code>：</p>
<div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb9-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> which hello</span>
<span id="cb9-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/Users/hjw/.nix-profile/bin/hello</span></span></code></pre></div>
<p>可以看到，<code>hello</code>来自于<code>$HOME/.nix-profile</code>，而后者是一个符号链接，其指向如下：</p>
<div class="cell" data-layout-align="default">
<div class="cell-output-display">
<div id="fig-nix-profile" class="quarto-float quarto-figure quarto-figure-center anchored">
<figure class="quarto-float quarto-float-fig figure">
<div aria-describedby="fig-nix-profile-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
<div>
<svg width="672" height="480" viewbox="0.00 0.00 405.83 260.00" xmlns="http://www.w3.org/2000/svg" xlink="http://www.w3.org/1999/xlink" style="; max-width: none; max-height: none">
<g id="graph0" class="graph" transform="scale(1 1) rotate(0) translate(4 256)">
<title>G</title>
<polygon fill="white" stroke="transparent" points="-4,4 -4,-256 401.83,-256 401.83,4 -4,4"></polygon>
<!-- a -->
<g id="node1" class="node">
<title>a</title>
<polygon fill="none" stroke="black" points="244.25,-252 153.58,-252 153.58,-216 244.25,-216 244.25,-252"></polygon>
<text text-anchor="middle" x="198.91" y="-229.8" font-family="Times,serif" font-size="14.00">~/.nix-profile</text>
</g>
<!-- b -->
<g id="node2" class="node">
<title>b</title>
<polygon fill="none" stroke="black" points="284.15,-180 113.68,-180 113.68,-144 284.15,-144 284.15,-180"></polygon>
<text text-anchor="middle" x="198.91" y="-157.8" font-family="Times,serif" font-size="14.00">/nix/var/nix/profiles/default</text>
</g>
<!-- a&#45;&gt;b -->
<g id="edge1" class="edge">
<title>a-&gt;b</title>
<path fill="none" stroke="black" d="M198.91,-215.7C198.91,-207.98 198.91,-198.71 198.91,-190.11"></path>
<polygon fill="black" stroke="black" points="202.41,-190.1 198.91,-180.1 195.41,-190.1 202.41,-190.1"></polygon>
</g>
<!-- c -->
<g id="node3" class="node">
<title>c</title>
<polygon fill="none" stroke="black" points="303.26,-108 94.57,-108 94.57,-72 303.26,-72 303.26,-108"></polygon>
<text text-anchor="middle" x="198.91" y="-85.8" font-family="Times,serif" font-size="14.00">/nix/var/nix/profiles/default-6-link</text>
</g>
<!-- b&#45;&gt;c -->
<g id="edge2" class="edge">
<title>b-&gt;c</title>
<path fill="none" stroke="black" d="M198.91,-143.7C198.91,-135.98 198.91,-126.71 198.91,-118.11"></path>
<polygon fill="black" stroke="black" points="202.41,-118.1 198.91,-108.1 195.41,-118.1 202.41,-118.1"></polygon>
</g>
<!-- d -->
<g id="node4" class="node">
<title>d</title>
<polygon fill="none" stroke="black" points="397.74,-36 0.09,-36 0.09,0 397.74,0 397.74,-36"></polygon>
<text text-anchor="middle" x="198.91" y="-13.8" font-family="Times,serif" font-size="14.00">/nix/store/hsw97dr9h9z3wmlwhx2lib8r3k2f9wv3-user-environment</text>
</g>
<!-- c&#45;&gt;d -->
<g id="edge3" class="edge">
<title>c-&gt;d</title>
<path fill="none" stroke="black" d="M198.91,-71.7C198.91,-63.98 198.91,-54.71 198.91,-46.11"></path>
<polygon fill="black" stroke="black" points="202.41,-46.1 198.91,-36.1 195.41,-46.1 202.41,-46.1"></polygon>
</g>
</g>
</svg>
</div>
</div>
<figcaption class="quarto-float-caption-bottom quarto-float-caption quarto-float-fig" id="fig-nix-profile-caption-0ceaefa1-69ba-4598-a22c-09a6ac19f8ca">
Figure&nbsp;1: Nix profile.
</figcaption>
</figure>
</div>
</div>
</div>
<p>进一步查看最后一个目录（省略部分输出）：</p>
<div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb10-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ls <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span> /nix/store/hsw97dr9h9z3wmlwhx2lib8r3k2f9wv3-user-environment</span>
<span id="cb10-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">bin</span></span>
<span id="cb10-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">etc</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/2vk1g8qkly4aqwx6ks49mzkd5kxhrd5f-nix-1.8pre3766_809ca33/etc</span>
<span id="cb10-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">include</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/2vk1g8qkly4aqwx6ks49mzkd5kxhrd5f-nix-1.8pre3766_809ca33/include</span>
<span id="cb10-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">……</span></span>
<span id="cb10-6"></span>
<span id="cb10-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ls <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span> /nix/store/hsw97dr9h9z3wmlwhx2lib8r3k2f9wv3-user-environment/bin</span>
<span id="cb10-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">ccmake</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/r5rr3h6fg9sb0vararwh3plm2v9p8hcm-cmake-2.8.12.2/bin/ccmake</span>
<span id="cb10-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">cmake</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/r5rr3h6fg9sb0vararwh3plm2v9p8hcm-cmake-2.8.12.2/bin/cmake</span>
<span id="cb10-10"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">……</span></span></code></pre></div>
<p>可以发现，实际的文件都是存在<code>/nix/store</code>中的。这也是Nix管理包的方式：所有的包都存放在<code>/nix/store</code>中，而用户访问的都是指向<code>/nix/store</code>中文件的符号链接。</p>
<p>Profile是Nix管理包的方式，在<code>/nix/var/nix/profiles</code>中保存了当前的profile：</p>
<div class="sourceCode" id="cb11" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb11-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ls <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span> /nix/var/nix/profiles</span>
<span id="cb11-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> default-6-link</span>
<span id="cb11-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default-5-link</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/g7l19z0c0ka41irwkn4mz67a0z85xydg-user-environment</span>
<span id="cb11-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default-6-link</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/hsw97dr9h9z3wmlwhx2lib8r3k2f9wv3-user-environment</span>
<span id="cb11-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">per-user</span></span></code></pre></div>
<p>其中<code>default</code>就是当前的profile。如果我们删除一个包呢？</p>
<div class="sourceCode" id="cb12" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb12-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-e</span> hello</span>
<span id="cb12-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">uninstalling</span> ‘hello-2.9’</span>
<span id="cb12-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">building</span> path<span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">s</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span> <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">‘/nix/store/816saagv6v8s19b2sksbgzjj0ljf5qfk-user-environment’</span></span>
<span id="cb12-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">created</span> 62 symlinks in user environment</span>
<span id="cb12-5"></span>
<span id="cb12-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ls <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span> /nix/var/nix/profiles</span>
<span id="cb12-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> default-7-link</span>
<span id="cb12-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default-5-link</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/g7l19z0c0ka41irwkn4mz67a0z85xydg-user-environment</span>
<span id="cb12-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default-6-link</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/hsw97dr9h9z3wmlwhx2lib8r3k2f9wv3-user-environment</span>
<span id="cb12-10"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default-7-link</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/816saagv6v8s19b2sksbgzjj0ljf5qfk-user-environment</span>
<span id="cb12-11"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">per-user</span></span></code></pre></div>
<p>注意到删除一个包会生成一个新的profile —— <code>default-7-link</code>，而<code>default</code>也会指向新生成的profile。这也是Nix的工作方式，你删除包的时候，包其实并没有被删除，而是生成了一个不包含原来包的新profile！而你随时可以回到原来的状态。如果我们后悔删除<code>hello</code>了，那么可以回滚上述操作：</p>
<div class="sourceCode" id="cb13" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb13-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> which hello</span>
<span id="cb13-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">hello</span> not found</span>
<span id="cb13-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--rollback</span></span>
<span id="cb13-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">switching</span> from generation 7 to 6</span>
<span id="cb13-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> which hello</span>
<span id="cb13-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/Users/hjw/.nix-profile/bin/hello</span></span>
<span id="cb13-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ls <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span> /nix/var/nix/profiles</span>
<span id="cb13-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> default-6-link</span>
<span id="cb13-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default-5-link</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/g7l19z0c0ka41irwkn4mz67a0z85xydg-user-environment</span>
<span id="cb13-10"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default-6-link</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/hsw97dr9h9z3wmlwhx2lib8r3k2f9wv3-user-environment</span>
<span id="cb13-11"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">default-7-link</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/store/816saagv6v8s19b2sksbgzjj0ljf5qfk-user-environment</span>
<span id="cb13-12"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">per-user</span></span></code></pre></div>
<p>可以看到，回滚之后<code>default</code>又指向了<code>default-6-link</code>，<code>hello</code>又可以用了。Profile使用起来非常灵活，我们可以很方便地在各个profile之间切换：</p>
<div class="sourceCode" id="cb14" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb14-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--list-generations</span></span>
<span id="cb14-2">   <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">5</span>   2014-09-13 20:58:33</span>
<span id="cb14-3">   <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">6</span>   2014-09-19 10:00:58   <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">current</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb14-4">   <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">7</span>   2014-09-21 21:16:57</span>
<span id="cb14-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--switch-generation</span> 7</span>
<span id="cb14-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">switching</span> from generation 6 to 7</span>
<span id="cb14-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--switch-profile</span> /nix/var/nix/profiles/my-profile</span>
<span id="cb14-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ls <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span> ~/.nix-profile</span>
<span id="cb14-9"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">/Users/hjw/.nix-profile</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/var/nix/profiles/my-profile</span></code></pre></div>
<p>如果我们从来不真正删除包，毫无疑问硬盘慢慢就会被占满，Nix支持垃圾回收。我们需要首先删除不用的profile：</p>
<div class="sourceCode" id="cb15" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb15-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--delete-generations</span> 5</span>
<span id="cb15-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">removing</span> generation 5</span>
<span id="cb15-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--delete-generations</span> old</span>
<span id="cb15-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">removing</span> generation 6</span>
<span id="cb15-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--list-generations</span></span>
<span id="cb15-6">   <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">7</span>   2014-09-21 21:16:57   <span class="er" style="color: #AD0000;
background-color: null;
font-style: inherit;">(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">current</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span></code></pre></div>
<p>然后，可以运行垃圾回收的命令。这里的垃圾回收跟编程语言的垃圾回收机制很像，一个包如果没有profile用到它就会被删除：</p>
<div class="sourceCode" id="cb16" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb16-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-store <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--gc</span></span></code></pre></div>
<p>如果你不确定哪些东西会被删除，可以先把要删除的东西打印一下看看：</p>
<div class="sourceCode" id="cb17" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb17-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-store <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--gc</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--print-dead</span></span></code></pre></div>
<p>还有另外一个命令，它会删除<code>/nix/var/nix/profiles</code>下所有profile的老版本，可以用来清理你的系统：</p>
<div class="sourceCode" id="cb18" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb18-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-collect-garbage <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-d</span></span></code></pre></div>
<p>Nix的profile其实是可以放在任意位置的，但是垃圾回收的时候之后回收<code>/nix/var/nix/gcroots</code>下所指向的那些profile目录：</p>
<div class="sourceCode" id="cb19" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb19-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ls <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-l</span> /nix/var/nix/gcroots</span>
<span id="cb19-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">auto</span></span>
<span id="cb19-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">profiles</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> /nix/var/nix/profiles</span></code></pre></div>
</section>
<section id="channel" class="level3">
<h3 class="anchored" data-anchor-id="channel">Channel</h3>
<p>Nix的Channel存储了包的集合，可以通过命令添加Channel：</p>
<div class="sourceCode" id="cb20" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb20-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-channel <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--add</span> http://nixos.org/channels/nixpkgs-unstable</span></code></pre></div>
<p>更新Channel:</p>
<div class="sourceCode" id="cb21" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb21-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-channel <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--update</span></span></code></pre></div>
<p>升级已有的包：</p>
<div class="sourceCode" id="cb22" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb22-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-env <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-u</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'*'</span></span></code></pre></div>
<p>此外，Nix还提供了很方便的工具让你把包及其依赖导出、导入以及通过SSH拷贝到另一台机器上：</p>
<div class="sourceCode" id="cb23" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb23-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-store <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--export</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">nix-store</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-qR</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-p</span> firefox<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">))</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span> firefox.closure</span>
<span id="cb23-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-store <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--import</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span> firefox.closure</span>
<span id="cb23-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> nix-copy-closure <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--to</span> alice@itchy.example.org <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$(</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-p</span> firefox<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">)</span></span></code></pre></div>
</section>
<section id="nix表达式" class="level3">
<h3 class="anchored" data-anchor-id="nix表达式">Nix表达式</h3>
<p>Nix的包是由Nix表达式描述的，它所使用的<a href="http://nixos.org/nix/manual/#idm47361539226272">Nix expression language</a>是一种支持惰性求值的纯函数式语言。下面是一个简单的<code>hello</code>包的描述：</p>
<div class="sourceCode" id="cb24" style="background: #f1f3f5;"><pre class="sourceCode nix code-with-copy"><code class="sourceCode nix"><span id="cb24-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">stdenv</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">fetchurl</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">perl</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span>:</span>
<span id="cb24-2"></span>
<span id="cb24-3">stdenv.mkDerivation <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb24-4">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">name</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"hello-2.1.v1"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb24-5">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">builder</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">./builder.sh</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb24-6">  <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">src</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> fetchurl <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb24-7">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">url</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">ftp</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">://</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">ftp.nluug.nl/pub/gnu/hello/hello-2.1.1.tar.gz</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb24-8">    <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">md5</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"70c9ccvf9fac07f762c24f2df2290784d"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb24-9">  <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">};</span></span>
<span id="cb24-10">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">inherit</span> perl<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb24-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>这个描述其实就是一个函数，<code>{stdenv, fetchurl, perl}</code>是函数的参数，表示构建这个包需要什么东西，<code>stdenv</code>提供了一个标准的构建环境，<code>fetchurl</code>通过url抓取一个文件，而<code>perl</code>是Perl的解释器。<code>mkDerivation</code>是<code>stdenv</code>提供的一个函数，它通过一个属性集合来构建一个包。<code>mkDerivation</code>的参数也就是后面花括弧括起来的那部分是一个集合，描述了这个包的属性，如名字、源代码、以及所需的解释器，其中的<code>builder</code>表示构建这个包的脚本：</p>
<div class="sourceCode" id="cb25" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb25-1"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">source</span> <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$stdenv</span>/setup</span>
<span id="cb25-2"></span>
<span id="cb25-3"><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">PATH</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$perl</span>/bin:<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$PATH</span></span>
<span id="cb25-4"></span>
<span id="cb25-5"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">tar</span> xvfz <span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$src</span></span>
<span id="cb25-6"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">cd</span> hello-<span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">*</span></span>
<span id="cb25-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">./configure</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--prefix</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">$out</span></span>
<span id="cb25-8"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">make</span> 5</span>
<span id="cb25-9"><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">make</span> install</span></code></pre></div>
<p>更具体的Nix expression这里就不赘述，有兴趣的可以查看相关文档。</p>
</section>
<section id="总结" class="level3">
<h3 class="anchored" data-anchor-id="总结">总结</h3>
<p>Nix是一个非常强大的包管理工具，它可以非常方便地解决包的依赖以及多版本共存的问题，对于那些没有包管理系统的语言（如C/C++）是一个比较好的选择；对于包管理很弱的语言（如Python）也能够提供一个更好的解决方法；对于涉及到多中语言的项目，能够以一种统一的方式来管理各种包，对开发者而言是一个非常好的工具。</p>
<p>此外，Nix所提供的包管理机制应该可以和Docker结合起来。比如本地开发的时候使用Nix，发布时将相关的包打包形成一个Docker镜像，实现<a href="http://martinfowler.com/bliki/ReproducibleBuild.html">可重现的构建</a>。</p>
<p>如果说Nix的缺点，那就是相比<code>apt</code>、<code>yum</code>、<code>pacman</code>、<code>homebrew</code>之类比较成熟的包管理器，它包的数量还比较少，特别是在Mac上，有很多包还是处于<code>broken</code>的状态。不过Nix的开发比较活跃，即使你现在还没有用它，也值得去关注一下。</p>
<p>最后说一句，Nix其实也<a href="http://nixos.org/wiki/Nix_impurities">不是真的纯函数式</a> :-)</p>


</section>

 ]]></description>
  <category>DevOps</category>
  <guid>https://hanjianwei.github.io/posts/2014/09/21/nix-the-purely-functional-package-manager/</guid>
  <pubDate>Sun, 21 Sep 2014 12:04:00 GMT</pubDate>
</item>
<item>
  <title>Webpack: 为Web开发而生的模块管理器</title>
  <link>https://hanjianwei.github.io/posts/2014/09/10/webpack-package-manager-for-web/</link>
  <description><![CDATA[ 





<p>对于开发人员而言，好的包管理器可以让工作事半功倍。现在流行的编程语言大多有自己的<a href="http://blogs.atlassian.com/2014/04/git-project-dependencies/#GitAndProjectDependencies-Firstchoice:useanappropriatebuild/dependencytoolinsteadofgit">包管理系统</a>。近年来，Web开发越来越火，其开发工具也随之越来越好用了，而<a href="http://webpack.github.io">Webpack</a>就是一款专为Web开发设计的包管理器。它能够很好地管理、打包Web开发中所用到的HTML、Javascript、CSS以及各种静态文件（图片、字体等），让开发过程更加高效。</p>
<section id="模块化编程" class="level3">
<h3 class="anchored" data-anchor-id="模块化编程">模块化编程</h3>
<p>长久以来，Web开发者都是把所需Javascript、CSS文件一股脑放进HTML里面，对于庞大的项目来说管理起来非常麻烦。<a href="http://nodejs.org">Node.js</a>的出现改变了这种状态，虽然Javascript的模块并非Node.js发明，但确实是它把这个概念发扬光大了。</p>
<p>但Node.js毕竟是用于服务端的，为了将模块化技术用于浏览器，人们又造出了一大堆工具：<a href="http://requirejs.org">RequireJS</a>、<a href="http://browserify.org">Browserify</a>、<a href="http://labjs.com">LABjs</a>、<a href="http://seajs.org/docs/">Sea.js</a>、<a href="http://duojs.org">Duo</a>等。同时，由于Javascript的标准没有对模块的规范进行定义，人们又定义了一系列不同的模块定义：<a href="https://en.wikipedia.org/wiki/CommonJS">CommonJS</a>、<a href="https://github.com/amdjs/amdjs-api/wiki/AMD">AMD</a>、<a href="https://github.com/seajs/seajs/issues/242">CMD</a>、<a href="https://github.com/umdjs/umd">UMD</a>等。这真是一件令人悲伤的事情，希望ES6 Module的出现能中止这种分裂的状态。</p>
<p>Webpack同时支持CommonJS和AMD形式的模块，对于不支持的模块格式，还支持对模块进行<a href="http://webpack.github.io/docs/shimming-modules.html">shimming</a>。举个简单的例子：</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb1-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// content.js</span></span>
<span id="cb1-2">module<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">exports</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"It works from content.js."</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb2-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// entry.js</span></span>
<span id="cb2-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">document</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">write</span>(<span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">require</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"./content.js"</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode html code-with-copy"><code class="sourceCode html"><span id="cb3-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;!-- index.html --&gt;</span></span>
<span id="cb3-2"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">html</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-3">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">head</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-4">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">meta</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> charset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utf-8"</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-5">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">head</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-6">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">body</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">script</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> type=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"text/javascript"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> src</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bundle.js"</span><span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;"> charset</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"utf-8"</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">script</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-8">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">body</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb3-9"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&lt;/</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">html</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">&gt;</span></span></code></pre></div>
<p>这里<code>entry.js</code>是入口文件，它加载了<code>content.js</code>。通过命令行对<code>entry.js</code>进行编译：</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> webpack ./entry.js bundle.js</span></code></pre></div>
<p>打开<code>index.html</code>就会看到<code>content.js</code>中的内容已经被加载进来了。</p>
<p>Web开发中用到的不但有Javascript，还有CSS以及各种静态文件。Webpack定义了一种叫<a href="http://webpack.github.io/docs/using-loaders.html">加载器loader</a>的东西，它能够把各种资源文件进行转换，用正确的格式加载到浏览器中。比如对于上述程序，如果我们有一个对应的CSS文件：</p>
<div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode css code-with-copy"><code class="sourceCode css"><span id="cb5-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">/* style.css */</span></span>
<span id="cb5-2">body {</span>
<span id="cb5-3">  <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">background</span><span class="ch" style="color: #20794D;
background-color: null;
font-style: inherit;">:</span> <span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">yellow</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb5-4">}</span></code></pre></div>
<p>我们修改一下<code>entry.js</code>来加载该CSS：</p>
<div class="sourceCode" id="cb6" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb6-1"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">require</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"!style!css!./style.css"</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb6-2"><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">document</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">write</span>(<span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">require</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"./content.js"</span>))<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div>
<p>然后再重新编译、打开<code>index.html</code>就可以看到CSS加载进来了。执行上述程序前我们必须安装所需的loader：</p>
<div class="sourceCode" id="cb7" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb7-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">npm</span> install <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--save-dev</span> style-loader css-loader</span></code></pre></div>
<p>在编译时，css-loader会读取CSS文件，并处理其中的import，返回CSS代码；而style-loader会将返回的CSS代码作为DOM的style。如果你用的是SASS，只要把require语句改成<code>require("!style!css!sass!./style.scss")</code>就可以了。</p>
<p>Webpack提供了很多<a href="http://webpack.github.io/docs/list-of-loaders.html">常见的loader</a>，开发的时候可以把用到的文件都require进来，生成一个单一的Javascript，便于发布。</p>
<p>上述require CSS的代码虽然功能强大，但写起来比较繁琐，Webpack支持在<a href="http://webpack.github.io/docs/using-loaders.html#configuration">配置文件中进行配置</a>，把符合条件的文件用同一组loader来进行处理。下面是我用的一组loader：</p>
<div class="sourceCode" id="cb8" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb8-1">{</span>
<span id="cb8-2">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">module</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb8-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loaders</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb8-4">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">coffee</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'coffee'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-5">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">html</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'html'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-6">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">json</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'json'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-7">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">css</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'style!css!autoprefixer'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-8">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">scss</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'style!css!autoprefixer!sass'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-9">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">woff</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"url?limit=10000&amp;minetype=application/font-woff"</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-10">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">ttf</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"file"</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-11">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">eot</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"file"</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb8-12">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">svg</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"file"</span>}</span>
<span id="cb8-13">    ]</span>
<span id="cb8-14">  }</span>
<span id="cb8-15">}</span></code></pre></div>
<p>有了上述配置，直接<code>require('./style.css')</code>就可以了，系统会自动先执行<a href="https://github.com/postcss/autoprefixer">autoprefixer</a>，然后加载CSS，然后再加载为DOM的style。</p>
<p>此外，Webpack还支持<a href="http://webpack.github.io/docs/list-of-plugins.html">插件</a>，实现对Javascript的压缩、替换等各种操作。</p>
</section>
<section id="依赖模块的管理" class="level3">
<h3 class="anchored" data-anchor-id="依赖模块的管理">依赖模块的管理</h3>
<p>Webpack自己并不提供模块的下载，但它可以和已有的包管理器很好的配合。你可以用<a href="http://npmjs.org/">npm</a>、<a href="http://bower.io">Bower</a>、<a href="https://github.com/componentjs/component">component</a>等来管理你的Web开发资源，同时在Webpack中加载它们。</p>
<p>Webpack的文件加载分为三种：</p>
<ul>
<li>绝对路径，比如<code>require('/home/me/file')</code>。此时会首先检查目标是否为目录，如果是目录则检查<code>package.json</code>的<code>main</code>字段（你可以让Webpack同时<a href="http://webpack.github.io/docs/usage-with-bower.html">检查Bower的字段</a>）；如果没有<code>package.json</code>或者没有<code>main</code>字段，则会用<code>index</code>作为文件名。经过上述过程，我们解析到一个绝对路径的文件名，然后会尝试为其加上扩展名（扩展名可在<code>webpack.config.js</code>中设置），第一个存在的文件作为最终的结果。</li>
<li>相对路径，比如<code>require('./file')</code>。使用当前路径或配置文件中的<code>context</code>作为相对路径的目录。加载过程和绝对路径相似。</li>
<li>模块路径，如<code>require('module/lib/file')</code>。会在配置文件中的所有查找目录中查找。</li>
</ul>
<p>对于复杂的模块路径，还可以设置别名。一个路径解析配置的例子：</p>
<div class="sourceCode" id="cb9" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb9-1">{</span>
<span id="cb9-2">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">resolve</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb9-3">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">root</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [appRoot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> nodeRoot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> bowerRoot]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb9-4">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">modulesDirectories</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [appModuleRoot]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb9-5">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">alias</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb9-6">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'angular'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'angular/angular'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb9-7">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lodash'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lodash/dist/lodash'</span></span>
<span id="cb9-8">    }<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb9-9">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">extensions</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.js'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.coffee'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.html'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.css'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.scss'</span>]</span>
<span id="cb9-10">  }</span>
<span id="cb9-11">}</span></code></pre></div>
</section>
<section id="工具的集成" class="level3">
<h3 class="anchored" data-anchor-id="工具的集成">工具的集成</h3>
<p>Webpack能够和<a href="http://webpack.github.io/docs/usage-with-grunt.html">grunt</a>、<a href="http://webpack.github.io/docs/usage-with-gulp.html">gulp</a>、<a href="http://webpack.github.io/docs/usage-with-karma.html">karma</a>等已有工具很好地集成。</p>
<p>此外，除了输出单一文件，Webpack还支持<a href="http://webpack.github.io/docs/code-splitting.html">代码分割</a>、<a href="http://webpack.github.io/docs/multiple-entry-points.html">多入口</a>以及<a href="http://webpack.github.io/docs/hot-module-replacement-with-webpack.html">运行时模块替换</a>，是非常值得Web开发者关注的一个工具。</p>
<p>最后附上我的配置文件：</p>
<div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode javascript code-with-copy"><code class="sourceCode javascript"><span id="cb10-1"><span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">// webpack.config.js</span></span>
<span id="cb10-2"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> path <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">require</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'path'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-3"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> webpack <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">require</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'webpack'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-4"></span>
<span id="cb10-5"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> appRoot <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">join</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">__dirname</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'app'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-6"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> appModuleRoot <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">join</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">__dirname</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'app/components'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-7"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> bowerRoot <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">join</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">__dirname</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'bower_components'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-8"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> nodeRoot <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">join</span>(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">__dirname</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'node_modules'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span>
<span id="cb10-9"></span>
<span id="cb10-10">module<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">exports</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> {</span>
<span id="cb10-11">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">entry</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'app'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-12">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">output</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb10-13">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">path</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> path<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">resolve</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'./app/assets'</span>)<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-14">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">filename</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'bundle.js'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-15">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">publicPath</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'/assets/'</span></span>
<span id="cb10-16">  }<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-17">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">resolve</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb10-18">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">root</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [appRoot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> nodeRoot<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> bowerRoot]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-19">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">modulesDirectories</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [appModuleRoot]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-20">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">alias</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb10-21">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'angular-ui-tree'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'angular-ui-tree/dist/'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-22">      <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'angular-date-range-picker'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'angular-date-range-picker/build/'</span></span>
<span id="cb10-23">    }<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-24">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">extensions</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">''</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.js'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.coffee'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.html'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.css'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'.scss'</span>]</span>
<span id="cb10-25">  }<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-26">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">resolveLoader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb10-27">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">root</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> nodeRoot</span>
<span id="cb10-28">  }<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-29">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">plugins</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb10-30">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> webpack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ProvidePlugin</span>({</span>
<span id="cb10-31">      <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">_</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'lodash'</span></span>
<span id="cb10-32">    })<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-33">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> webpack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">ResolverPlugin</span>([</span>
<span id="cb10-34">      <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">new</span> webpack<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">ResolverPlugin</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">.</span><span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">DirectoryDescriptionFilePlugin</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"bower.json"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> [<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"main"</span>])</span>
<span id="cb10-35">    ])</span>
<span id="cb10-36">  ]<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-37">  <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">module</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> {</span>
<span id="cb10-38">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loaders</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> [</span>
<span id="cb10-39">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">coffee</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'coffee'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-40">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">html</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'html'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-41">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">json</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'json'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-42">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">css</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'style!css!autoprefixer'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-43">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">scss</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'style!css!autoprefixer!sass'</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-44">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">woff</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>   <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"url?limit=10000&amp;minetype=application/font-woff"</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-45">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">ttf</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"file"</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-46">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">eot</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"file"</span>}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb10-47">      {<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">test</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">\.</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">svg</span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">$</span><span class="ss" style="color: #20794D;
background-color: null;
font-style: inherit;">/</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span>    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">loader</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"file"</span>}</span>
<span id="cb10-48">    ]</span>
<span id="cb10-49">  }</span>
<span id="cb10-50">}<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">;</span></span></code></pre></div>


</section>

 ]]></description>
  <category>WebDev</category>
  <guid>https://hanjianwei.github.io/posts/2014/09/10/webpack-package-manager-for-web/</guid>
  <pubDate>Wed, 10 Sep 2014 12:04:00 GMT</pubDate>
</item>
<item>
  <title>阿里云服务器的Docker配置</title>
  <link>https://hanjianwei.github.io/posts/2014/07/30/docker-on-aliyun/</link>
  <description><![CDATA[ 





<p>最近把程序放到<a href="http://www.aliyun.com">阿里云</a>服务器上，并尝试用<a href="https://www.docker.com">Docker</a>来部署。阿里云的镜像列表里面已经有了Ubuntu 14.04 64位，可以直接<a href="https://docs.docker.com/installation/ubuntulinux/">安装Docker</a>。然而，由于阿里云服务器的特殊情况，需要进行配置才能用。</p>
<p>安装完Docker之后，发现Docker服务并没有起来，检查日志发现有这么一段：</p>
<pre class="plaintext"><code>[/var/lib/docker|3c476c9d] -job init_networkdriver() = ERR (1)
Could not find a free IP address range for interface 'docker0'. Please configure its address manually and run 'docker -b docker0'</code></pre>
<p>搜了下Docker的issues，发现<a href="https://github.com/docker/docker/issues/362">这个问题</a>挺多人遇到过。究其原因，要从Docker的启动过程说起，在<a href="https://docs.docker.com/articles/networking/">Docker的文档</a>中有这么一段话：</p>
<blockquote class="blockquote">
<p>When Docker starts, it creates a virtual interface named docker0 on the host machine. It randomly chooses an address and subnet from the private range defined by RFC 1918 that are not in use on the host machine, and assigns it to docker0.</p>
</blockquote>
<p>也就是说，Docker在启动时，会创建一个虚拟接口<code>docker0</code>，并为其选择一个没有在宿主机器上使用的地址和子网。这个<code>docker0</code>其实并非一般的网络接口，而是一个虚拟的网桥（Ethernet Bridge），其作用是为了容器（Container）和宿主（Host）机器之间的通信。每当Docker启动一个容器时，它都会创建一对对等接口（“peer” interface）。这对接口有点类似于管道，向其中的一个接口发送数据包，另外一个接口就会接收到。Docker把其中的一个接口分配给容器，作为它的<code>eth0</code>接口；然后，为另外一个接口分配一个唯一的名字比如<code>vethAQI2QT</code>，将其分配给宿主机器，并将其绑定到<code>docker0</code>这个网桥上。这样每个容器都可以和宿主机器进行通信了。</p>
<p>那么，在阿里云中为什么会启动失败呢？在<a href="https://github.com/docker/docker">Docker的源代码</a>搜索上述错误信息，可以看出问题出在<a href="https://github.com/docker/docker/blob/4398108433121ce2ac9942e607da20fa1680871a/daemon/networkdriver/bridge/driver.go#L246">createBridge</a>这个函数中。该函数会检查<a href="https://github.com/docker/docker/blob/503d124677f5a0221e1bf8c8ed7320a15c5e01db/daemon/networkdriver/bridge/driver.go#L53-L70">下列IP段</a>:</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode go code-with-copy"><code class="sourceCode go"><span id="cb2-1"><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">var</span> addrs <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">[]</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">string</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">{</span></span>
<span id="cb2-2">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"172.17.42.1/16"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-3">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"10.0.42.1/16"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-4">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"10.1.42.1/16"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-5">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"10.42.42.1/16"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-6">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"172.16.42.1/24"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-7">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"172.16.43.1/24"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-8">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"172.16.44.1/24"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-9">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"10.0.42.1/24"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-10">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"10.0.43.1/24"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-11">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.42.1/24"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-12">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.43.1/24"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-13">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"192.168.44.1/24"</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">,</span></span>
<span id="cb2-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span></span></code></pre></div>
<p>对于每个IP段，Docker会检查它是否和当前机器的域名服务器或路由表有重叠，如果有的话，就放弃该IP段。让我们看看阿里云服务器的路由表：</p>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> route <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-n</span></span>
<span id="cb3-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">Destination</span>     Gateway         Genmask         Flags Metric Ref    Use Iface</span>
<span id="cb3-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">0.0.0.0</span>         121.40.83.247   0.0.0.0         UG    0      0        0 eth1</span>
<span id="cb3-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">10.0.0.0</span>        10.171.223.247  255.0.0.0       UG    0      0        0 eth0</span>
<span id="cb3-5"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">10.171.216.0</span>    0.0.0.0         255.255.248.0   U     0      0        0 eth0</span>
<span id="cb3-6"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">121.40.80.0</span>     0.0.0.0         255.255.252.0   U     0      0        0 eth1</span>
<span id="cb3-7"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">172.16.0.0</span>      10.171.223.247  255.240.0.0     UG    0      0        0 eth0</span>
<span id="cb3-8"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">192.168.0.0</span>     10.171.223.247  255.255.0.0     UG    0      0        0 eth0</span></code></pre></div>
<p>检查一下路由表会发现，Docker所检查的IP段在路由表中都有了，所以不能找到一个有效的IP段。</p>
<p>解决方法其实也很简单，简单粗暴的方法就是把内网的网卡信息直接删掉，它在路由表中所对应的信息也没有了:</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb4-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> sudo ifconfig eth0 down</span></code></pre></div>
<p>这种方法的缺点也很明显：你就无法访问内网了，而阿里云的内部流量是不收费的（用mirrors.aliyuncs.com来升级不占用公网流量），这点还是比较可惜的。</p>
<p>另一种方法是把路由表中不用的项删除，这样Docker就能找到能用的IP段了：</p>
<div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb5-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> sudo route del <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-net</span> 172.16.0.0/12</span>
<span id="cb5-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> sudo service docker start</span>
<span id="cb5-3"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ifconfig docker0</span>
<span id="cb5-4"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">docker0</span>   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99</span>
<span id="cb5-5">          <span class="ex" style="color: null;
background-color: null;
font-style: inherit;">inet</span> addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0</span></code></pre></div>
<p>重新启动服务，可以看到<code>docker0</code>已经建立成功，所用的IP地址就是我们删除路由表项之后腾出来的IP地址。采用这种方法，我们仍然可以使用内网的服务。如果要每次启动的时候设置，编辑<code>/etc/network/interfaces</code>，将<code>up route add -net 172.16.0.0 ....</code>那一行删掉即可。</p>



 ]]></description>
  <category>DevOps</category>
  <guid>https://hanjianwei.github.io/posts/2014/07/30/docker-on-aliyun/</guid>
  <pubDate>Wed, 30 Jul 2014 12:04:00 GMT</pubDate>
</item>
<item>
  <title>快速构建Mac环境</title>
  <link>https://hanjianwei.github.io/posts/2014/07/15/1-click-building-your-mac-environment/</link>
  <description><![CDATA[ 





<p>最近硬盘不幸挂掉，换了新硬盘后重装系统、搭建环境真是一个痛苦的过程。尤其是后者，各种软件的配置、开发环境的设定，非常繁琐。这里索性总结一下，怎么能够将开发、应用的环境配置系统化，使得更换系统时能够迅速重建原来的环境。这里虽然是针对Mac来说的，对于Linux应该也类似。</p>
<p>作为一个开发者用户，我关心的数据主要有以下几类：</p>
<ol type="1">
<li>代码</li>
<li>各种资料、数据（照片、视频、文档、程序数据等）</li>
<li>应用程序及其配置信息</li>
<li>系统配置信息</li>
</ol>
<p>对于代码而言，如果是开源的，放在GitHub是最好的方案；如果是内部代码，可以考虑用<a href="https://about.gitlab.com">GitLab</a>搭建一个私有服务器来存放代码，当然也可以放在Dropbox之类的网盘上。对于资料文档以及比较大的数据，可以放在网盘上。无论是代码还是文档，除了网上存储之外，最好能定期备份到移动硬盘上，一来是防止网盘出问题，二来是大数据从网盘下载较慢，如果急用就比较痛苦了。所以这里我们主要侧重于后面两点：应用程序的安装配置及系统的配置。</p>
<section id="使用homebrew管理程序" class="level3">
<h3 class="anchored" data-anchor-id="使用homebrew管理程序">使用Homebrew管理程序</h3>
<p>Mac中的App主要有两类：一类是从App Store中安装的；另一类是下载安装的。对于前者，没有什么太好的办法，到Purchased里面一个个重新装过就好了；对于后者，用<a href="http://brew.sh">Homebrew</a>来管理更加方便，相比直接的下载安装而言，它是更容易自动化、更易重现的方式。</p>
<p>对于dmg和pkg程序，可以用<a href="http://caskroom.io">Homebrew Cask</a>来安装。</p>
<p>如果要装的程序没有在Homebrew或者Cask里面，可以在你的GitHub中<a href="https://github.com/hanjianwei/homebrew-apps">建立一个Repo</a>来存放相关的Formula/Cask，然后用<a href="https://github.com/Homebrew/homebrew/wiki/brew-tap">brew tap</a>将其加到Homebrew中。</p>
<p>Homebrew的好处是，你很容易将当前安装的程序列表<a href="http://www.topbug.net/blog/2013/12/07/back-up-homebrew-packages/">备份</a>起来以备下次安装。另外一种备份方法是采用<a href="https://coderwall.com/p/afmnbq">Brewfile</a>，不过Homebrew<a href="https://github.com/Homebrew/homebrew/pull/30749">已经后悔把这东西加进去了</a>，以后也许会有更好的方案出现吧。</p>
</section>
<section id="管理配置文件" class="level3">
<h3 class="anchored" data-anchor-id="管理配置文件">管理配置文件</h3>
<p>安装程序其实只是最简单的一步，更麻烦的是如何对这些程序进行配置。当前一个很流行的方式是把你的配置文件放在一个<a href="http://dotfiles.github.io">Dotfiles</a>的<a href="https://github.com/hanjianwei/dotfiles">Repo</a>里，然后将其符号链接到相应的位置。然后你就可以用Git轻松管理你的配置文件了。对于包含敏感信息无法放在GitHub中的信息，也可以放在Dropbox中。</p>
<p>把所有程序的配置文件都搜集起来当然是一件非常繁琐的事情，而<a href="https://github.com/lra/mackup">Mackup</a>可以把你从这件事情里面解放出来，它记录了很多程序的配置文件，从而能够自动在系统中搜索这些配置文件，备份到你的目录中，然后再符号链接到相应的位置。结合GitHub或者Dropbox来进行备份，真是太方便了！</p>
<p>Dotfiles中还可以保存一些常用的脚本，比如<a href="https://github.com/mathiasbynens/dotfiles/blob/master/.osx">mathiasbynens的dotfiles</a>中就包含了很多OSX的设置脚本，一键运行完成你大部分的系统设置。</p>
<p>然而，单靠配置文件有时候也不能完全解决问题，比如安装vim的时候，希望不但能保留.vimrc之类的配置文件，还希望能把所有的插件装上去。这时候就需要介绍下面一个系统了：Boxen。</p>
</section>
<section id="用boxen自动化环境设置" class="level3">
<h3 class="anchored" data-anchor-id="用boxen自动化环境设置">用Boxen自动化环境设置</h3>
<p><a href="https://boxen.github.com">Boxen</a>是GitHub的自动化部署工具，它能够快速为新员工构建一个开发环境。Boxen基于<a href="https://puppetlabs.com">Puppet</a>，它针对Mac系统做了一系列的设置，使得环境配置更加方便快捷。关于Boxen的介绍可以看看<a href="http://garylarizza.com/blog/2013/02/15/puppet-plus-github-equals-laptop-love/">Gary Larizza的这篇博客</a>.</p>
<p>GitHub提供了一个Boxen工程的模板，叫做<a href="https://github.com/boxen/our-boxen">our-boxen</a>，只要将其fork并安装<a href="https://github.com/boxen/our-boxen#getting-started">说明文档</a>安装即可。安装完的our-boxen包含了一个基本的开发环境（Ruby、node等），你可以在此基础上加入你自己的东西。一般来说，你可以在modules目录里面添加相关的内容：people添加和用户相关的内容，projects中添加工程相关的内容。我的个人设置在<a href="https://github.com/hanjianwei/my-boxen/tree/master/modules/people/manifests">这里</a>。</p>
<p>对系统默认参数的一些配置（比如全局的Ruby版本）可以通过Hiera实现，具体参考<a href="https://github.com/hanjianwei/my-boxen/blob/master/hiera/common.yaml.example">相关说明</a>。你可以针对用户进行一些设置，<a href="https://github.com/hanjianwei/my-boxen/blob/master/hiera/users/hanjianwei.yaml">这里</a>是我的个人设置。</p>
<p>你甚至可以把<a href="https://github.com/hanjianwei/my-boxen/blob/master/modules/people/manifests/hanjianwei/repositories.pp">代码的Repo</a>和<a href="https://github.com/hanjianwei/my-boxen/blob/master/modules/people/manifests/hanjianwei/osx.pp">系统相关的配置</a>写在文件里，下次部署时直接搞定。</p>
<p>Boxen支持Homebrew/Cask，所以我们上面<a href="https://github.com/hanjianwei/my-boxen/blob/master/modules/people/manifests/hanjianwei/applications.pp">安装的App可以直接写文件中</a>，下次部署时只要一个<code>boxen</code>命令即可。Boxen自身也只是App的安装，其<a href="https://github.com/boxen">GitHub帐户</a>中包含了很多可用的App，和Homebrew/Cask相比，这些App的更新可能相对较慢，但一般会提供更多的配置选项。对于简单的的应用，我一般使用Homebrew/Cask来管理，对于配置比较复杂的（如Ruby）我会采用Boxen提供的版本。</p>
<p>此外，我写了一个puppet的模块<a href="https://github.com/hanjianwei/puppet-dotfiles">puppet-dotfiles</a>，可以使用Mackup兼容的配置文件，直接在Boxen工程中进行配置，使得程序的配置更加自动化。该模块除了用Mackup的配置文件，还会进行了一些其它的设置，比如安装vim的时候会安装上<a href="https://github.com/gmarik/Vundle.vim">Vundle</a>及其它插件、自动安装<a href="https://github.com/sorin-ionescu/prezto">prezto</a>及其模块等。</p>
<p>Boxen的另外一个好处是删除简单，只要把<code>/opt/boxen</code>删除即可（当然可能你还要删除<code>/opt</code>下的<code>homebrew-cask</code>之类的）。</p>
</section>
<section id="缓存安装文件" class="level3">
<h3 class="anchored" data-anchor-id="缓存安装文件">缓存安装文件</h3>
<p>虽然上述过程能够大大减轻你的负担，但是在恶劣的网络环境中，下载安装文件就会成为一个瓶颈。我的解决方案是：缓存安装文件。</p>
<p>Homebrew/Cask安装程序时会把安装文件缓存下来，下次重装的时候就不会再次下载了。我的Mac是11年的型号，光驱位换了SSD，所以就把这些缓存文件备份到原来的硬盘：</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> mv <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">brew</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--cache</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/Volumes/Macintosh HD/"</span></span>
<span id="cb1-2"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> ln <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">-s</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"/Volumes/Macintosh HD/cache"</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">brew</span> <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--cache</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">`</span></span></code></pre></div>
<p>这样万一SSD坏掉，重装起来也会比较快一点。</p>
<p>当然，编译也是一项非常耗时的任务，这个问题主要存在Homebrew中（因为Cask只是些dmg、pkg）。不过Homebrew非常佛心地提供了编译好的二进制版本（叫做<a href="https://github.com/Homebrew/homebrew/wiki/Bottles#bottle-creation">Bottle</a>），只要你用默认选项安装，就会使用二进制版本，免去你的编译之苦。然而，不幸的是，某些程序的编译过程需要具体的路径信息（比如Qt），Homebrew默认是安装在<code>/usr/local</code>的，而Boxen把Homebrew安装在了<code>/opt/boxen/homebrew</code>中，所以就<a href="https://github.com/boxen/puppet-homebrew/issues/8">不能享受到这项好处了</a>，希望将来能够有所改进吧！</p>
</section>
<section id="其它方案" class="level3">
<h3 class="anchored" data-anchor-id="其它方案">其它方案</h3>
<p>对于这样一个常见问题，肯定是有很多方案的，这里有一些供参考的其它方案：</p>
<ul>
<li><a href="http://osxc.github.io">osxc</a>: 基于<a href="http://osxc.github.io">Ansible</a>的一套方案。</li>
<li><a href="https://github.com/spencergibb/battleschool">battleschool</a>: 也是基于Ansible的方案。</li>
<li><a href="https://github.com/kitchenplan/kitchenplan">kitchenplan</a>: 基于<a href="http://www.getchef.com">Chef</a>的方案。</li>
<li><a href="https://github.com/thoughtbot/laptop">thoughtbot/laptop</a>: 用于Mac和Linux安装配置的一套脚本。</li>
</ul>
<p>其实还有很多……<a href="https://github.com/hanjianwei/feedback/issues/new">说说你的方案吧</a>。</p>


</section>

 ]]></description>
  <category>DevOps</category>
  <guid>https://hanjianwei.github.io/posts/2014/07/15/1-click-building-your-mac-environment/</guid>
  <pubDate>Tue, 15 Jul 2014 02:23:00 GMT</pubDate>
</item>
<item>
  <title>走马观花看Puppet</title>
  <link>https://hanjianwei.github.io/posts/2014/07/14/master-of-puppets/</link>
  <description><![CDATA[ 





<p><a href="http://puppetlabs.com">Puppet</a>是目前最流行的一套<a href="http://en.wikipedia.org/wiki/Configuration_management">配置管理(Configuration Management，简称CM)</a>系统。它提供了一套简洁、强大的框架，使系统管理的重用、分享更加简单，让系统配置更加自动化。在云计算时代，动辄需要配置大量主机，它的作用更加明显。</p>
<p>Puppet使用一种声明式的语言，和传统的脚本相比，你只需指定目标，而不必关注具体的执行细节。举个例子，比如我们要建立一个文件<code>/tmp/foobar.txt</code>，其内容为<code>Hello World!</code>，在Puppet中这么写就行了：</p>
<pre class="puppet"><code>file { '/tmp/foobar.txt':
  ensure  =&gt; present,
  content =&gt; 'Hello World!',
}</code></pre>
<p>将上述内容保存为<code>test.pp</code>（称为<a href="https://docs.puppetlabs.com/pe/latest/puppet_modules_manifests.html#manifests">manifest</a>），然后执行<code>puppet apply test.pp</code>，就会确保存在一个文件<code>/tmp/foobar.txt</code>，其中的内容为「Hello World!」。在这个过程中，Puppet会检查我们声明的条件是否满足，如果满足就什么也不做；如果不满足就执行相应的操作以满足我们的要求，而这个过程对用户来说是完全透明的，你不用写各种脚本去执行各种检测和修改。</p>
<p>在Puppet中，<code>file</code>是一种<code>资源(resource)</code>。<a href="http://docs.puppetlabs.com/puppet/3.6/reference/lang_resources.html">资源</a>是一个相当广的概念，用户、软件包、文件、服务甚至Git的库都是资源，用<code>puppet describe -l</code>可以查看系统中所有的资源类型。每种资源都有一个类型（如<code>file</code>），一个名字（如<code>/tmp/foobar.txt</code>）以及一系列的属性（如<code>ensure</code>、<code>content</code>等），可以通过<code>puppet describe &lt;resource_type&gt;</code>得到资源的具体描述。</p>
<p>通过资源声明就可以完成一些基本的任务，比如要配置一个ssh服务：</p>
<pre class="puppet"><code># /root/examples/break_ssh.pp
file { '/etc/ssh/sshd_config':
  ensure =&gt; file,
  mode   =&gt; 600,
  source =&gt; '/root/examples/sshd_config',
}

service { 'sshd':
  ensure     =&gt; running,
  enable     =&gt; true,
  subscribe  =&gt; File['/etc/ssh/sshd_config'],
}</code></pre>
<p>其中声明了两个资源：一个配置文件，权限为<code>600</code>，内容从<code>/root/examples/sshd_config</code>复制；一个服务<code>sshd</code>，确保其处于运行状态。值得注意的是，上述<code>sshd</code>资源的最后一项是<code>subscribe</code>，这是什么东西呢？原来在Puppet中，执行顺序并不是按照资源的声明顺序来的，在上述例子中，就有可能<code>sshd</code>服务先启动起来，然后配置文件才生成，这种情况配置文件就不起作用了。</p>
<p>Puppet提供了一系列方法来<a href="http://docs.puppetlabs.com/learning/ordering.html">确保资源的执行顺序</a>，上述的<code>subscribe</code>属于<a href="http://docs.puppetlabs.com/learning/ordering.html#metaparameters-resource-references-and-ordering">metaparameter</a>，它表示当配置文件<code>/etc/ssh/sshd_config</code>修改后，自动重启<code>sshd</code>。其中<code>File['/etc/ssh/sshd_config']</code>是对资源的引用。除了metaparameter之外，还可以用<a href="http://docs.puppetlabs.com/learning/ordering.html#chaining-arrows">箭头</a>来表示顺序，上述例子也可以这么写：</p>
<pre class="puppet"><code># /root/examples/break_ssh.pp
file { '/etc/ssh/sshd_config':
  ensure =&gt; file,
  mode   =&gt; 600,
  source =&gt; '/root/examples/sshd_config',
}
~&gt;
service { 'sshd':
  ensure     =&gt; running,
  enable     =&gt; true,
}</code></pre>
<p>当资源不多时，把所有东西都写到一个巨大的manifest里面还可以接受；随着你维护的东西越来越多，这种方法会让你的代码越来越难维护。Puppet提供了<a href="http://docs.puppetlabs.com/learning/modules1.html">class和module</a>使得我们能够更加模块化地管理代码。</p>
<p>如果你像我一样从其它编程语言过来，那么很可能会被class这个关键字所迷惑：Puppet中的class不像C++或Java之类语言中的class，它只是一段有名字的代码。你可以用class把相关的代码包装起来，使其重用起来更加方便。比如上述代码可以修改为：</p>
<pre class="puppet"><code>class ssh {
  file { '/etc/ssh/sshd_config':
    ensure =&gt; file,
    mode   =&gt; 600,
    source =&gt; '/root/examples/sshd_config',
  }
  service { 'sshd':
    ensure     =&gt; running,
    enable     =&gt; true,
    subscribe  =&gt; File['/etc/ssh/sshd_config'],
  }
}

include ssh</code></pre>
<p>需要注意的是，class只是定义了一段代码，只有<code>include</code>之后才会声明其中的资源。同一个class可以<code>include</code>多次，效果和<code>include</code>一次一样。然而，即使有了class，我们的代码仍然在一个巨大的manifest里面啊！这里就要提到<a href="http://docs.puppetlabs.com/learning/modules1.html#modules">module</a>了。</p>
<p>Module其实就是目录，它根据特定的<a href="http://docs.puppetlabs.com/learning/modules1.html#module-structure">结构</a>来组织目录，并且其中的manifest符合一定的<a href="http://docs.puppetlabs.com/learning/modules1.html#organizing-and-referencing-manifests">命名规则</a>。Puppet在<a href="http://docs.puppetlabs.com/learning/modules1.html#the-modulepath">modulepath</a>中搜索module，如果一个类在module中出现了，那么你可以在任何其它的manifest中声明它。比如要配置一个Apache服务器，可以把apache作为一个模块，而mod、proxy、vhost的设置都可以作为其中的manifest。</p>
<p>Puppet中可以使用<a href="http://docs.puppetlabs.com/learning/variables.html">变量</a>，变量以<code>$</code>开头。变量是有<a href="http://docs.puppetlabs.com/puppet/latest/reference/lang_scope.html">作用域</a>的，子作用域可以访问父作用域的变量，但访问其它作用域的变量就要加上module和class前缀（如<code>$apache::params::confdir</code>）。此外，变量支持双引号字符串插值：<code>"The value is ${variable}"</code>。</p>
<p>上述例子中，ssh配置文件的模板位置是固定的。但是，实际应用中往往根据不同的情况做修改，我们不可能针对每种情况写一个class。为此，可以使用<a href="http://docs.puppetlabs.com/learning/modules2.html">带参数的class</a>，上述例子可以修改为：</p>
<pre class="puppet"><code>class ssh ($config_path = '/root/examples/ssd_config') {
  file { '/etc/ssh/sshd_config':
    ensure =&gt; file,
    mode   =&gt; 600,
    source =&gt; "${config_path}",
  }
  service { 'sshd':
    ensure     =&gt; running,
    enable     =&gt; true,
    subscribe  =&gt; File['/etc/ssh/sshd_config'],
  }
}

class { 'ssh':
  config_path =&gt; '/home/jack/ssd_config',
}</code></pre>
<p>注意要使用带参数的class，就不能直接用<code>include ssh</code>（否则会使用默认参数），而是要用资源式的class声明方式，将参数作为属性传递进去，在这种情况下应该仔细组织manifest文件，不要将一个class声明两次。参数类的另外一种使用方法是通过<a href="http://docs.puppetlabs.com/hiera/1/puppet.html">Hiera</a>来设置参数，这种方式能够尽量把代码和数据分开，是一种推荐的使用方式。</p>
<p>即使class可以设置参数，但是我们也只能设置一组参数，如果我们需要同时设置多组参数呢？比如Apache的vhost，我们希望能够设置多个vhost，比如：</p>
<pre class="puppet"><code>apache::vhost {'users.example.com':
  port    =&gt; 80,
  docroot =&gt; '/var/www/personal',
  options =&gt; 'Indexes MultiViews',
}
apache::vhost {'projects.example.com':
  port    =&gt; 80,
  docroot =&gt; '/var/www/project',
  options =&gt; 'Indexes MultiViews',
}</code></pre>
<p>这时候我们就需要define类型了，它所定义的类型和系统提供的资源类似，可以同时声明多个不同参数的资源。举个例子：</p>
<pre class="puppet"><code>define planfile ($user = $title, $content) {
  file {"/home/${user}/.plan":
    ensure  =&gt; file,
    content =&gt; $content,
    mode    =&gt; 0644,
    owner   =&gt; $user,
    require =&gt; User[$user],
  }
}
planfile {'nick':
  content =&gt; "working on foobar"
}
planfile {'katie':
  content =&gt; "working on cookies"
}</code></pre>
<p>要发挥Puppet最大的优势，必须了解<a href="http://docs.puppetlabs.com/learning/agent_master_basic.html">Agent/Master Puppet</a>（为什么现在都不用Master/Slave了？看<a href="https://github.com/django/django/pull/2692">这里</a>）。不过我暂时都是单机用用，就先不去了解了。</p>
<p>当然了，题目就叫走马观花，看这篇Blog你是不可能完全掌握Puppet的啦，感兴趣就去看看<a href="https://puppetlabs.com/download-learning-vm">tutorial</a>和<a href="http://docs.puppetlabs.com/puppet/latest/reference/">reference</a>吧！</p>



 ]]></description>
  <category>DevOps</category>
  <guid>https://hanjianwei.github.io/posts/2014/07/14/master-of-puppets/</guid>
  <pubDate>Mon, 14 Jul 2014 08:18:00 GMT</pubDate>
</item>
<item>
  <title>Docker on Mac</title>
  <link>https://hanjianwei.github.io/posts/2014/06/06/docker-on-mac/</link>
  <description><![CDATA[ 





<p>在虚拟化领域，<a href="https://www.docker.io">Docker</a>是一颗冉冉升起的新星。它构建于<a href="http://en.wikipedia.org/wiki/Lxc">LXC</a>之上，比传统的虚拟机技术相比，它没有操作系统层，因此更加轻量化，灵活性和可移植性也更好。</p>
<p>Docker有两个主要的部件：daemon和作为客户端的二进制程序「docker」。docker作为客户端，把相应指令发送给daemon来执行。因为Docker使用了Linux内核的一些特性，因此只能运行在具体比较新内核的64位Linux上，其它平台上必须借助虚拟机才能运行。</p>
<p>在Mac上，主要有两种基于VirtualBox的运行方式：第一种是借助<a href="https://github.com/boot2docker/boot2docker">boot2docker</a>；第二种是使用<a href="http://www.vagrantup.com">Vagrant</a>来管理虚拟机。</p>
<p>boot2docker使用了一个非常轻量的Linux发行版<a href="https://coreos.com">CoreOS</a>来作为Docker的运行环境，启动很快、占用空间很少。通过<a href="http://brew.sh">Homebrew</a>来安装非常方便：</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb1-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> brew install boot2docker docker</span></code></pre></div>
<p>boot2docker的一个问题是和Mac之间共享文件非常不方便，官方给出的方案是<a href="https://github.com/boot2docker/boot2docker#folder-sharing">用Samba来共享文件</a>。</p>
<p>我更喜欢的一种方式是用Vagrant来管理Docker。Vagrant是一个管理虚拟机的软件，1.6版本加入了对<a href="http://www.vagrantup.com/blog/feature-preview-vagrant-1-6-docker-dev-environments.html">Docker的支持</a>，可以在Vagrant中对Docker进行管理。Vagrant可以把<a href="http://docs.vagrantup.com/v2/docker/index.html">Docker作为Provider</a>，在Vagrantfile配置Docker相关的操作。一个简单的Vagrantfile的例子：</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb2-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Vagrant</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.configure</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2"</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span>config<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span></span>
<span id="cb2-2">  config<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.vm.provider</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"docker"</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span>d<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span></span>
<span id="cb2-3">    d<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.image</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"ubuntu:14.04"</span></span>
<span id="cb2-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb2-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div>
<p>这个配置文件表示，启动Docker的时候使用<code>ubuntu:14.04</code>这个image。然后，执行操作：</p>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb3-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> vagrant up <span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">--provider</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span>docker</span></code></pre></div>
<p>在非Linux系统上，Docker是需要运行在虚拟机中的。如果没有配置虚拟机（比如上述例子），Vagrant会自动使用<a href="https://github.com/mitchellh/vagrant/blob/master/plugins/providers/docker/hostmachine/Vagrantfile">boot2docker</a>作为虚拟机。当然，你可以指定一个已有的Vagrantfile作为Docker的运行主机：</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb4-1"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Vagrant</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.configure</span>(<span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2"</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span>config<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span></span>
<span id="cb4-2">  config<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.vm.provider</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"docker"</span> <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span>d<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span></span>
<span id="cb4-3">    d<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.vagrant_vagrantfile</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"../path/to/Vagrantfile"</span></span>
<span id="cb4-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb4-5"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div>
<p>同直接使用boot2docker相比，Vagrant提供了非常便捷的手段处理Mac和虚拟机之间的交互，如<a href="http://docs.vagrantup.com/v2/synced-folders/index.html">文件夹同步</a>、<a href="http://docs.vagrantup.com/v2/networking/forwarded_ports.html">端口映射</a>等。在进行文件夹同步时，Vagrant会尝试使用最佳方式进行同步，比如对boot2docker会使用rsync进行同步。</p>
<p>boot2docker虽然比较精简，但是功能毕竟有限，我使用了一个Ubuntu 14.04来作为Docker的运行主机，相应的Vagrantfile如下：</p>
<div class="sourceCode" id="cb5" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb5-1"><span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">VAGRANTFILE_API_VERSION</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"2"</span></span>
<span id="cb5-2"></span>
<span id="cb5-3"><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Vagrant</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.configure</span>(<span class="cn" style="color: #8f5902;
background-color: null;
font-style: inherit;">VAGRANTFILE_API_VERSION</span>) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">do</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span>config<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">|</span></span>
<span id="cb5-4">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Box</span></span>
<span id="cb5-5">  config<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.vm.box</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"phusion/ubuntu-14.04-amd64"</span></span>
<span id="cb5-6">  config<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.vm.box_check_update</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">false</span></span>
<span id="cb5-7"></span>
<span id="cb5-8">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Provisioners</span></span>
<span id="cb5-9">  config<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.vm.provision</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"shell"</span>, <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">path: </span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"apt.sh"</span></span>
<span id="cb5-10">  config<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.vm.provision</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"docker"</span></span>
<span id="cb5-11">  config<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.vm.provision</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"shell"</span>, <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">path: </span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"docker.sh"</span></span>
<span id="cb5-12"></span>
<span id="cb5-13">  config<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.vm.network</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"forwarded_port"</span>, <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">guest: </span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4243</span>, <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">host: </span><span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">4243</span></span>
<span id="cb5-14"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span></code></pre></div>
<p>注意中间的<a href="http://docs.vagrantup.com/v2/provisioning/index.html">Provisioner部分</a>，Vagrant的Provisioner的主要作用是自动安装一些软件、执行一些任务。上面的<code>apt.sh</code>是一个脚本，用来修改Ubuntu的apt源；<code>docker.sh</code>用来修改Docker的配置参数。值得注意的是，Vagrant还提供了<a href="http://docs.vagrantup.com/v2/provisioning/docker.html">Docker的Provisoner</a>，用来安装、配置Docker。当你运行的虚拟机中没有安装Docker时，它会自动帮你安装最新的Docker。</p>
<p>在最后一行，我设置了一个端口映射，将虚拟机的Docker daemon的端口4243映射到本地，这样就可以使用Mac中Homebrew所带的docker客户端来执行相应的操作了（要注意Mac客户端的版本需和虚拟机中Docker daemon的版本一致）。</p>
<p>我们只要运行<code>vagrant up</code>，Docker的运行环境就搭建好了。Vagrant中有很多对Docker的支持，使得我们能够更方便地自动化搭建开发、部署环境，具体可以参考<a href="http://docs.vagrantup.com/v2/">Vagrant</a>和<a href="http://docs.docker.io">Docker</a>的文档。</p>



 ]]></description>
  <category>DevOps</category>
  <guid>https://hanjianwei.github.io/posts/2014/06/06/docker-on-mac/</guid>
  <pubDate>Fri, 06 Jun 2014 07:58:00 GMT</pubDate>
</item>
<item>
  <title>混乱的标点符号</title>
  <link>https://hanjianwei.github.io/posts/2013/07/26/punctuation/</link>
  <description><![CDATA[ 





<p>打开你经常上的几个网站，翻开你正在看的书，拿起你身边商品的包装，仔细观察一下其中的标点，有没有被用法各异的标点所困扰？中、英文之间的差异，输入法之间的差异，排版软件处理细节的不同，让标点符号变得异常混乱。</p>
<section id="引号撇号上标符" class="level2">
<h2 class="anchored" data-anchor-id="引号撇号上标符">引号、撇号、上标符</h2>
<p>首先是「引号」及其面目相似的兄弟们：</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>符号</th>
<th>Unicode</th>
<th>名称</th>
<th>HTML</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>’</td>
<td>U+0027</td>
<td>单直引号</td>
<td><code>&amp;apos;</code></td>
</tr>
<tr class="even">
<td>”</td>
<td>U+0022</td>
<td>双直引号</td>
<td><code>&amp;quot;</code></td>
</tr>
<tr class="odd">
<td>‘</td>
<td>U+2018</td>
<td>单开弯引号</td>
<td><code>&amp;lsquo;</code></td>
</tr>
<tr class="even">
<td>’</td>
<td>U+2019</td>
<td>单闭弯引号</td>
<td><code>&amp;rsquo;</code></td>
</tr>
<tr class="odd">
<td>“</td>
<td>U+201C</td>
<td>双开弯引号</td>
<td><code>&amp;ldquo;</code></td>
</tr>
<tr class="even">
<td>”</td>
<td>U+201D</td>
<td>双闭弯引号</td>
<td><code>&amp;rdquo;</code></td>
</tr>
<tr class="odd">
<td>′</td>
<td>U+2032</td>
<td>上标符</td>
<td><code>&amp;prime;</code></td>
</tr>
<tr class="even">
<td>″</td>
<td>U+2033</td>
<td>双上标符</td>
<td><code>&amp;Prime;</code></td>
</tr>
</tbody>
</table>
<p>计算机键盘沿用了打字机的做法，将上述符号浓缩为两个：单直引号（’）和双直引号（“）。ASCII 码中也只收录了这两个字符，所以在早期的电子文档中大多是这两者身兼多职。这种引号通常叫做「Typewriter (“programmer’s”) straight quotes」——「打字机（程序员）直引号」：</p>
<blockquote class="blockquote">
<p>“Good morning, Frank,” said Hal.</p>
<p>don’t</p>
<p>’06</p>
<p>the cat’s whiskers.</p>
<p>6’ 2” tall.</p>
</blockquote>
<p>为了更好的阅读体验，也有用<a href="http://en.wikipedia.org/wiki/Grave_accent">重音符（反引号）</a>（`）来作为左引号的（如TeX）：</p>
<blockquote class="blockquote">
<p>``Good morning, Frank,” said Hal.</p>
</blockquote>
<p>随着 Unicode 的普及，计算机显示各种字符已经不成问题，让各个标点各司其职才能取得更好的阅读体验。上述标点符号应按照如下规则使用：</p>
<ul>
<li>用弯引号「’’」、「“”」作为单、双引号。</li>
</ul>
<blockquote class="blockquote">
<p>“Good morning, Frank,” said Hal.</p>
<p>‘Good morning, Frank,’ said Hal.</p>
</blockquote>
<ul>
<li>撇号「’」用于缩写词、复数、所有格以及拼音分隔等。</li>
</ul>
<blockquote class="blockquote">
<p>don’t</p>
<p>’06</p>
<p>the cat’s whiskers.</p>
<p>Xi’an</p>
</blockquote>
<ul>
<li>上标符「′」、「″」用于表示单位、数学公式等。</li>
</ul>
<blockquote class="blockquote">
<p>6′ 2″ tall.</p>
<p>Tx = x′</p>
</blockquote>
<ul>
<li>直引号「’」，「“」只用于编程。</li>
</ul>
<blockquote class="blockquote">
<p>char *s = “Hello world”;</p>
<p>char c = ‘A’;</p>
</blockquote>
</section>
<section id="连字号连接号" class="level2">
<h2 class="anchored" data-anchor-id="连字号连接号">连字号、连接号</h2>
<p>另几个长得比较像的是连字号和连接号：</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>符号</th>
<th>Unicode</th>
<th>名称</th>
<th>HTML</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>-</td>
<td>U+002D</td>
<td>连字暨减号</td>
<td></td>
</tr>
<tr class="even">
<td>‐</td>
<td>U+2010</td>
<td>连字号</td>
<td></td>
</tr>
<tr class="odd">
<td>−</td>
<td>U+2212</td>
<td>减号</td>
<td><code>&amp;minus;</code></td>
</tr>
<tr class="even">
<td>‒</td>
<td>U+2012</td>
<td>数字线</td>
<td></td>
</tr>
<tr class="odd">
<td>–</td>
<td>U+2013</td>
<td>En dash</td>
<td><code>&amp;ndash;</code></td>
</tr>
<tr class="even">
<td>—</td>
<td>U+2014</td>
<td>Em dash</td>
<td><code>&amp;mdash;</code></td>
</tr>
</tbody>
</table>
<p>在 ASCII 中，「-」既当减号又当连字号，有时候几个组合起来作为连接号。在 UNICODE 中这几种符号都有了单独的字符。</p>
<ul>
<li>连字号用于标志合成词或用于断字。</li>
</ul>
<blockquote class="blockquote">
<p>ice‐cream‐flavored candy.</p>
<p>We, therefore, the represen‐</p>
<p>tatives of the United States</p>
<p>of America…</p>
</blockquote>
<ul>
<li>数字线用于连接数字（如电话号码中间的短线）。</li>
</ul>
<blockquote class="blockquote">
<p>0571‒87932195</p>
</blockquote>
<ul>
<li>En dash 通常是 Em dash 的一半，它们的大小分别是大写字母 N 和 M 的宽度。En dash主要用于表示数值范围、对比的数值、相关的两件事或者合成词的属性部分。</li>
</ul>
<blockquote class="blockquote">
<p>June–July 1967</p>
<p>Australia beat American Samoa 31–0.</p>
<p>Pre–Civil War era</p>
</blockquote>
<ul>
<li>Em dash 表示语气转折，类似于中文的破折号。</li>
</ul>
<p>Dash 的用法比较复杂，各种类似的符号及其用法可以参见 <a href="http://en.wikipedia.org/wiki/Dash">Wikipedia</a>。</p>
</section>
<section id="中文引号" class="level2">
<h2 class="anchored" data-anchor-id="中文引号">中文引号</h2>
<p>中文的引号和英文的引号一样，都是用的弯引号，它们的 UNICODE 值也是一样的。这样导致一个问题：在文中出现引号时，是当成中文的全角呢还是英文的半角呢？因此使用<a href="http://www.zhihu.com/topic/19691803">直角引号</a>「『』」的逐渐多了起来。</p>
<table class="caption-top table">
<thead>
<tr class="header">
<th>符号</th>
<th>Unicode</th>
<th>名称</th>
<th>HTML</th>
</tr>
</thead>
<tbody>
<tr class="odd">
<td>「</td>
<td>U+300C</td>
<td>中式单开引号</td>
<td></td>
</tr>
<tr class="even">
<td>」</td>
<td>U+300D</td>
<td>中式单闭引号</td>
<td></td>
</tr>
<tr class="odd">
<td>『</td>
<td>U+300E</td>
<td>中式双开引号</td>
<td></td>
</tr>
<tr class="even">
<td>』</td>
<td>U+300F</td>
<td>中式双闭引号</td>
<td></td>
</tr>
</tbody>
</table>
</section>
<section id="中英文混排" class="level2">
<h2 class="anchored" data-anchor-id="中英文混排">中英文混排</h2>
<p>有一种观点是混排时在中英文之间加上空格，在这方面还没有明确的规范。Adobe InDesign、Microsoft Word等软件在进行中英文混排时都会增大汉字与英文的间距，在这种情况下添加空格就没有必要；然而，大多数情况下我们没有这样的专业排版软件支持，这种情况下要想达到较好的排版效果就需要在汉字和西文之间加上半角的空格。<a href="http://www.zhihu.com/question/19587406">刘昕@知乎</a>认为：</p>
<blockquote class="blockquote">
<p>中文正文及标题中出现的英文及数字应该使用半角方式输入，并且在左右各留一个半角空格。如果这些这些半角英文及数字的左边或者右边紧接着任何的中文全角括号或者其他标点符号的话，则不需要加入半角空格。</p>
</blockquote>
<p>而<a href="http://www.zhihu.com/question/19695720">梁海@知乎</a>认为中英文混排中使用什么样的标点符号取决于「环境」：</p>
<blockquote class="blockquote">
<p>事实上我自己考虑排版的时候从来不从“什么夹杂什么”的角度来看问题，我的思路永远是“环境”。就是说，在我写一段文字的时候，我会有自己的意识，意识到这段文字本质上是什么语言环境，然后以此为基础。而且基本环境中也会有子环境，比如一本中文译文的全部脚注或者某一条脚注或者正文中的一大段引文完全可以是一个英文环境（但我在做这样排版的时候会尽量不让它成为一个英文子环境），然后在中文正文中的一大段英文引文中如果再出现括号内的中文解释，我会酌情使用英文括号。你那最后一句话在我看来仍旧是中文环境，中文的逗号和问号都暗示/表明了这一点，这句话还不够独立。</p>
</blockquote>
<p>具体采用什么样的方案要看使用场景，如果能从技术上做到中英文的隔离那是最好的了。</p>
</section>
<section id="输入" class="level2">
<h2 class="anchored" data-anchor-id="输入">输入</h2>
<p>规范使用标点符号最大的障碍在于输入。大部分标点符号都是 UNICODE 的，键盘很难直接输入。根据应用场景的不同大致有以下一些方法：</p>
<ul>
<li>Microsoft Word、Open Office 等软件本身提供了一些自动输入的方法，可以根据语境选择正确的标点符号。</li>
<li>输入法一般会为标点输入提供一些便捷。特别要推荐「<a href="http://code.google.com/p/rimeime/">中州韻</a>」输入法，它不但跨平台，还提供了强大的配置方案。</li>
<li>HTML 可以使用「<a href="http://en.wikipedia.org/wiki/Numeric_character_reference">字符值引用</a>」。</li>
<li>Windows 可以用下「<a href="http://en.wikipedia.org/wiki/Alt_code">Alt code</a>」。</li>
<li>Mac 下可以在「Unicode Hex Input」键盘下用「Option + xxxx」输入，其中 xxxx 表示十六进制的 UNICODE 值。</li>
<li>其它的输入方法参见 <a href="http://en.wikipedia.org/wiki/Unicode_input">Wikipedia</a>。</li>
</ul>


</section>

 ]]></description>
  <category>Writing</category>
  <guid>https://hanjianwei.github.io/posts/2013/07/26/punctuation/</guid>
  <pubDate>Fri, 26 Jul 2013 02:33:00 GMT</pubDate>
</item>
<item>
  <title>Python的方法解析顺序(MRO)</title>
  <link>https://hanjianwei.github.io/posts/2013/07/25/python-mro/</link>
  <description><![CDATA[ 





<p>对于支持继承的编程语言来说，其方法（属性）可能定义在当前类，也可能来自于基类，所以在方法调用时就需要对当前类和基类进行搜索以确定方法所在的位置。而搜索的顺序就是所谓的「方法解析顺序」（Method Resolution Order，或MRO）。对于只支持单继承的语言来说，MRO 一般比较简单；而对于 Python 这种支持多继承的语言来说，MRO 就复杂很多。</p>
<p>先看一个「菱形继承」的例子：</p>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">classDiagram
    class A {
        +show()
    }
    class B
    class C {
        +show()
    }
    class D


    A &lt;|-- B
    A &lt;|-- C
    B &lt;|-- D
    C &lt;|-- D
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>如果 <code>x</code> 是 <code>D</code> 的一个实例，那么 <code>x.show()</code> 到底会调用哪个 <code>show</code> 方法呢？如果按照 <code>[D, B, A, C]</code> 的搜索顺序，那么 <code>x.show()</code> 会调用 <code>A.show()</code>；如果按照 <code>[D, B, C, A]</code> 的搜索顺序，那么 <code>x.show()</code> 会调用 <code>C.show()</code>。由此可见，MRO 是把类的继承关系线性化的一个过程，而线性化方式决定了程序运行过程中具体会调用哪个方法。既然如此，那什么样的 MRO 才是最合理的？Python 中又是如何实现的呢？</p>
<p>Python 至少有<a href="http://python-history.blogspot.com/2010/06/method-resolution-order.html">三种不同的 MRO</a>：</p>
<ol type="1">
<li>经典类（classic class）的深度遍历。</li>
<li>Python 2.2 的新式类（new-style class）预计算。</li>
<li>Python 2.3 的新式类的<a href="http://en.wikipedia.org/wiki/C3_linearization">C3 算法</a>。它也是 Python 3 唯一支持的方式。</li>
</ol>
<section id="经典类的-mro" class="level3">
<h3 class="anchored" data-anchor-id="经典类的-mro">经典类的 MRO</h3>
<p>Python 有<a href="http://wiki.python.org/moin/NewClassVsClassicClass">两种类</a>：经典类（classic class）和新式类（new-style class）。两者的不同之处在于新式类继承自 <code>object</code>。在 Python 2.1 以前，经典类是唯一可用的形式；Python 2.2 引入了新式类，使得类和内置类型更加统一；在 Python 3 中，新式类是唯一支持的类。</p>
<p>经典类采用了一种很简单的 MRO 方法：从左至右的<a href="http://en.wikipedia.org/wiki/Depth-first_search">深度优先遍历</a>。以上述「菱形继承」为例，其查找顺序为 <code>[D, B, A, C, A]</code>，如果只保留重复类的第一个则结果为 <code>[D, B, A, C]</code>。我们可以用 <code>inspect.getmro</code> 来获取类的 MRO：</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb1-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="im" style="color: #00769E;
background-color: null;
font-style: inherit;">import</span> inspect</span>
<span id="cb1-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> A:</span>
<span id="cb1-3">...     <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> show(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb1-4">...         <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A.show()"</span></span>
<span id="cb1-5">...</span>
<span id="cb1-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> B(A): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb1-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> C(A):</span>
<span id="cb1-8">...     <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> show(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb1-9">...         <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"C.show()"</span></span>
<span id="cb1-10">...</span>
<span id="cb1-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> D(B, C): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb1-12"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> inspect.getmro(D)</span>
<span id="cb1-13">(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> __main__.D at <span class="bn" style="color: #AD0000;
background-color: null;
font-style: inherit;">0x105f0a6d0</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> __main__.B at <span class="bn" style="color: #AD0000;
background-color: null;
font-style: inherit;">0x105f0a600</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> __main__.A at <span class="bn" style="color: #AD0000;
background-color: null;
font-style: inherit;">0x105f0a668</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> __main__.C at <span class="bn" style="color: #AD0000;
background-color: null;
font-style: inherit;">0x105f0a738</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>)</span>
<span id="cb1-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> D()</span>
<span id="cb1-15"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> x.show()</span>
<span id="cb1-16">A.show()</span></code></pre></div>
<p>这种深度优先遍历对于简单的情况还能处理的不错，但是对于上述「菱形继承」其结果却不尽如人意：虽然 <code>C.show()</code> 是 <code>A.show()</code> 的更具体化版本（显示了更多的信息），但我们的 <code>x.show()</code> 没有调用它，而是调用了 <code>A.show()</code>。这显然不是我们希望的结果。</p>
<p>对于新式类而言，所有的类都继承自 <code>object</code>，所以「菱形继承」是非常普遍的现象，因此不可能采用这种 MRO 方式。</p>
</section>
<section id="python-2.2-的新式类-mro" class="level3">
<h3 class="anchored" data-anchor-id="python-2.2-的新式类-mro">Python 2.2 的新式类 MRO</h3>
<p>为解决经典类 MRO 所存在的问题，Python 2.2 针对新式类提出了一种新的 MRO 计算方式：在定义类时就计算出该类的 MRO 并将其作为类的属性。因此新式类可以直接通过 <code>__mro__</code> 属性获取类的 MRO。</p>
<p>Python 2.2 的新式类 MRO 计算方式和经典类 MRO 的计算方式非常相似：它仍然采用从左至右的深度优先遍历，但是如果遍历中出现重复的类，只保留最后一个。重新考虑上面「菱形继承」的例子，由于新式类继承自 <code>object</code> 因此类图稍有改变：</p>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">classDiagram
    class object
    class A {
        +show()
    }
    class B
    class C {
        +show()
    }
    class D

    object &lt;|-- A 
    A &lt;|-- B
    A &lt;|-- C
    B &lt;|-- D
    C &lt;|-- D
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>按照深度遍历，其顺序为 <code>[D, B, A, object, C, A, object]</code>，重复类只保留最后一个，因此变为 <code>[D, B, C, A, object]</code>。代码为：</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb2-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> A(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">object</span>):</span>
<span id="cb2-2">...     <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> show(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb2-3">...         <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"A.show()"</span></span>
<span id="cb2-4">...</span>
<span id="cb2-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> B(A): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb2-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> C(A):</span>
<span id="cb2-7">...     <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> show(<span class="va" style="color: #111111;
background-color: null;
font-style: inherit;">self</span>):</span>
<span id="cb2-8">...         <span class="bu" style="color: null;
background-color: null;
font-style: inherit;">print</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"C.show()"</span></span>
<span id="cb2-9">...</span>
<span id="cb2-10"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> D(B, C): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb2-11"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> D.__mro__</span>
<span id="cb2-12">(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.D'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.B'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.C'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.A'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'object'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>)</span>
<span id="cb2-13"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> x <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">=</span> D()</span>
<span id="cb2-14"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> x.show()</span>
<span id="cb2-15">C.show()</span></code></pre></div>
<p>这种 MRO 方式已经能够解决「菱形继承」问题，再让我们看个稍微复杂点的例子：</p>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">classDiagram
    class object
    class X
    class Y
    class A
    class B
    class C

    object &lt;|-- X
    object &lt;|-- Y
    X &lt;|-- A
    Y &lt;|-- A
    X &lt;|-- B
    Y &lt;|-- B
    A &lt;|-- C
    B &lt;|-- C
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<div class="sourceCode" id="cb3" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb3-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> X(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">object</span>): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb3-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> Y(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">object</span>): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb3-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> A(X, Y): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb3-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> B(Y, X): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb3-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> C(A, B): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span></code></pre></div>
<p>首先进行深度遍历，结果为 <code>[C, A, X, object, Y, object, B, Y, object, X, object]</code>；然后，只保留重复元素的最后一个，结果为 <code>[C, A, B, Y, X, object]</code>。Python 2.2 在实现该方法的时候进行了调整，使其更尊重基类中类出现的顺序，其实际结果为 <code>[C, A, B, X, Y, object]</code>。</p>
<p>这样的结果是否合理呢？首先我们看下各个类中的方法解析顺序：对于 <code>A</code> 来说，其搜索顺序为 <code>[A, X, Y, object]</code>；对于 <code>B</code>，其搜索顺序为 <code>[B, Y, X, object]</code>；对于 <code>C</code>，其搜索顺序为 <code>[C, A, B, X, Y, object]</code>。我们会发现，<code>B</code> 和 <code>C</code> 中 <code>X</code>、<code>Y</code> 的搜索顺序是相反的！也就是说，当 <code>B</code> 被继承时，它本身的行为竟然也发生了改变，这很容易导致不易察觉的错误。此外，即使把 <code>C</code> 搜索顺序中 <code>X</code> 和 <code>Y</code> 互换仍然不能解决问题，这时候它又会和 <code>A</code> 中的搜索顺序相矛盾。</p>
<p>事实上，不但上述特殊情况会出现问题，在<a href="http://mail.python.org/pipermail/python-dev/2002-October/029035.html">其它情况</a>下也可能出问题。其原因在于，上述继承关系违反了线性化的「 <strong>单调性原则</strong> 」。<a href="http://www.python.org/download/releases/2.3/mro/">Michele Simionato</a>对单调性的定义为：</p>
<blockquote class="blockquote">
<p>A MRO is monotonic when the following is true: if C1 precedes C2 in the linearization of C, then C1 precedes C2 in the linearization of any subclass of C. Otherwise, the innocuous operation of deriving a new class could change the resolution order of methods, potentially introducing very subtle bugs.</p>
</blockquote>
<p>也就是说，子类不能改变基类的方法搜索顺序。在 Python 2.2 的 MRO 算法中并不能保证这种单调性，它不会阻止程序员写出上述具有二义性的继承关系，因此很可能成为错误的根源。</p>
<p>除了单调性之外，Python 2.2 及 经典类的 MRO 也可能违反继承的「 <strong>局部优先级</strong> 」，具体例子可以参见<a href="http://www.python.org/download/releases/2.3/mro/#bad-method-resolution-orders">官方文档</a>。采用一种更好的 MRO 方式势在必行。</p>
</section>
<section id="c3-mro" class="level3">
<h3 class="anchored" data-anchor-id="c3-mro">C3 MRO</h3>
<p>为解决 Python 2.2 中 MRO 所存在的问题，Python 2.3以后采用了<a href="http://en.wikipedia.org/wiki/C3_linearization">C3 方法</a>来确定方法解析顺序。你如果在 Python 2.3 以后版本里输入上述代码，就会产生一个异常，禁止创建具有二义性的继承关系：</p>
<div class="sourceCode" id="cb4" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb4-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> C(A, B): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb4-2">Traceback (most recent call last):</span>
<span id="cb4-3">  File <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"&lt;ipython-input-8-01bae83dc806&gt;"</span>, line <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">1</span>, <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">in</span> <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span>module<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span></span>
<span id="cb4-4">    <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> C(A, B): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb4-5"><span class="pp" style="color: #AD0000;
background-color: null;
font-style: inherit;">TypeError</span>: Error when calling the metaclass bases</span>
<span id="cb4-6">    Cannot create a consistent method resolution</span>
<span id="cb4-7">order (MRO) <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">for</span> bases X, Y</span></code></pre></div>
<p>我们把类 <code>C</code> 的线性化（MRO）记为 <code>L[C] = [C1, C2,…,CN]</code>。其中 <code>C1</code> 称为 <code>L[C]</code> 的头，其余元素 <code>[C2,…,CN]</code> 称为尾。如果一个类 <code>C</code> 继承自基类 <code>B1</code>、<code>B2</code>、……、<code>BN</code>，那么我们可以根据以下两步计算出 <code>L[C]</code>：</p>
<ol type="1">
<li><code>L[object] = [object]</code></li>
<li><code>L[C(B1…BN)] = [C] + merge(L[B1]…L[BN], [B1]…[BN])</code></li>
</ol>
<p>这里的关键在于 <code>merge</code>，其输入是一组列表，按照如下方式输出一个列表：</p>
<ol type="1">
<li>检查第一个列表的头元素（如 <code>L[B1]</code> 的头），记作 <code>H</code>。</li>
<li>若 <code>H</code> 未出现在其它列表的尾部，则将其输出，并将其从所有列表中删除，然后回到步骤1；否则，取出下一个列表的头部记作 <code>H</code>，继续该步骤。</li>
<li>重复上述步骤，直至列表为空或者不能再找出可以输出的元素。如果是前一种情况，则算法结束；如果是后一种情况，说明无法构建继承关系，Python 会抛出异常。</li>
</ol>
<p>该方法有点类似于图的<a href="http://en.wikipedia.org/wiki/Topological_sorting">拓扑排序</a>，但它同时还考虑了基类的出现顺序。我们用 C3 分析一下刚才的例子。</p>
<p><code>object</code>，<code>X</code>，<code>Y</code> 的线性化结果比较简单：</p>
<pre class="plaintext"><code>L[object] = [object]
L[X] = [X, object]
L[Y] = [Y, object]</code></pre>
<p><code>A</code> 的线性化计算如下：</p>
<pre class="plaintext"><code>L[A] = [A] + merge(L[X], L[Y], [X], [Y])
     = [A] + merge([X, object], [Y, object], [X], [Y])
     = [A, X] + merge([object], [Y, object], [Y])
     = [A, X, Y] + merge([object], [object])
     = [A, X, Y, object]</code></pre>
<p>注意第3步，<code>merge([object], [Y, object], [Y])</code> 中首先输出的是 <code>Y</code> 而不是 <code>object</code>。这是因为 <code>object</code> 虽然是第一个列表的头，但是它出现在了第二个列表的尾部。所以我们会跳过第一个列表，去检查第二个列表的头部，也就是 <code>Y</code>。<code>Y</code> 没有出现在其它列表的尾部，所以将其输出。</p>
<p>同理，<code>B</code> 的线性化结果为：</p>
<pre class="plaintext"><code>L[B] = [B, Y, X, object]</code></pre>
<p>最后，我们看看 <code>C</code> 的线性化结果：</p>
<pre class="plaintext"><code>L[C] = [C] + merge(L[A], L[B], [A], [B])
     = [C] + merge([A, X, Y, object], [B, Y, X, object], [A], [B])
     = [C, A] + merge([X, Y, object], [B, Y, X, object], [B])
     = [C, A, B] + merge([X, Y, object], [Y, X, object])</code></pre>
<p>到了最后一步我们没有办法继续计算下去 了：<code>X</code> 虽然是第一个列表的头，但是它出现在了第二个列表的尾部；<code>Y</code> 虽然是第二个列表的头，但是它出现在了第一个列表的尾部。因此，我们无法构建一个没有二义性的继承关系，只能手工去解决（比如改变 <code>B</code> 基类中 <code>X</code>、<code>Y</code> 的顺序）。</p>
<p>我们再看一个没有冲突的例子：</p>
<div class="cell" data-layout-align="center">
<div class="cell-output-display">
<div>
<p></p><figure class="figure"><p></p>
<div>
<pre class="mermaid mermaid-js">classDiagram
    class object
    class A
    class B
    class C
    class D
    class E
    class F

    object &lt;|-- D
    object &lt;|-- E
    object &lt;|-- F
    D &lt;|-- B
    D &lt;|-- C
    E &lt;|-- B
    F &lt;|-- C
    B &lt;|-- A
    C &lt;|-- A
</pre>
</div>
<p></p></figure><p></p>
</div>
</div>
</div>
<p>计算过程如下：</p>
<pre class="plaintext"><code>L[object] = [object]
L[D] = [D, object]
L[E] = [E, object]
L[F] = [F, object]
L[B] = [B, D, E, object]
L[C] = [C, D, F, object]
L[A] = [A] + merge(L[B], L[C], [B], [C])
     = [A] + merge([B, D, E, object], [C, D, F, object], [B], [C])
     = [A, B] + merge([D, E, object], [C, D, F, object], [C])
     = [A, B, C] + merge([D, E, object], [D, F, object])
     = [A, B, C, D] + merge([E, object], [F, object])
     = [A, B, C, D, E] + merge([object], [F, object])
     = [A, B, C, D, E, F] + merge([object], [object])
     = [A, B, C, D, E, F, object]</code></pre>
<p>当然，可以用代码验证类的 MRO，上面的例子可以写作：</p>
<div class="sourceCode" id="cb10" style="background: #f1f3f5;"><pre class="sourceCode python code-with-copy"><code class="sourceCode python"><span id="cb10-1"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> D(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">object</span>): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb10-2"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> E(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">object</span>): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb10-3"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> F(<span class="bu" style="color: null;
background-color: null;
font-style: inherit;">object</span>): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb10-4"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> B(D, E): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb10-5"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> C(D, F): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb10-6"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> A(B, C): <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">pass</span></span>
<span id="cb10-7"><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;&gt;&gt;</span> A.__mro__</span>
<span id="cb10-8">(<span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.A'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.B'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.C'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.D'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.E'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'__main__.F'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>, <span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&lt;</span><span class="bu" style="color: null;
background-color: null;
font-style: inherit;">type</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'object'</span><span class="op" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">&gt;</span>)</span></code></pre></div>


</section>

 ]]></description>
  <category>Programming</category>
  <guid>https://hanjianwei.github.io/posts/2013/07/25/python-mro/</guid>
  <pubDate>Thu, 25 Jul 2013 12:34:00 GMT</pubDate>
</item>
<item>
  <title>Markdown 的 Ansi 显示</title>
  <link>https://hanjianwei.github.io/posts/2013/04/06/markdown-to-ansi/</link>
  <description><![CDATA[ 





<p>随着 Jekyll、Octopres、Docpad 等一批静态博客生成器的兴起，Markdown 已经成为写博客的利器。不过，有时候想把博客上的文章直接贴到 BBS 上还是需要去做一些转换，把格式转换为 ANSI 颜色控制符。</p>
<p>原因主要有二：</p>
<ol type="1">
<li>直接复制网页有些链接就只有文字没有 URL，同时代码高亮之类的就没了。</li>
<li>直接粘贴 Markdown 会引入一些不必要的字符（比如代码块的标记等）。</li>
</ol>
<p>看 <a href="https://github.com/vmg/redcarpet">Redcarpet</a> 的介绍发现它支持自定义 Render，于是就写了个 Markdown 到 Ansi 的工具。原理很简单：首先，Redcarpet 把 Markdown 解析为一系列的元素；然后，定义 <code>Redcarpet::Render::Base</code> 的子类对这些元素进行处理。这里用 <a href="http://rubyworks.github.io/ansi/">ansi</a> 来对文字进行着色，用 <a href="https://github.com/tmm1/pygments.rb">Pygments.rb</a> 来对代码进行高亮。代码如下：</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode ruby code-with-copy"><code class="sourceCode ruby"><span id="cb1-1"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">class</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Ansi</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">&lt;</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Redcarpet</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Render</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Base</span></span>
<span id="cb1-2">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> normal_text(text)</span>
<span id="cb1-3">    text<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.strip</span></span>
<span id="cb1-4">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-5"></span>
<span id="cb1-6">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> block_code(code, language)</span>
<span id="cb1-7">    <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Pygments</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.highlight</span>(code,</span>
<span id="cb1-8">                       <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">:lexer</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> language,</span>
<span id="cb1-9">                       <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">:formatter</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> <span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">'terminal'</span>) <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">+</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">"\n\n"</span></span>
<span id="cb1-10">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-11"></span>
<span id="cb1-12">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">def</span> double_emphasis(text)</span>
<span id="cb1-13">    <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">" </span><span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">#{</span>ansi(text, <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">:yellow</span>, <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">:on_red</span>)<span class="sc" style="color: #5E5E5E;
background-color: null;
font-style: inherit;">}</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;"> "</span></span>
<span id="cb1-14">  <span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-15"></span>
<span id="cb1-16">  <span class="co" style="color: #5E5E5E;
background-color: null;
font-style: inherit;"># Other elements goes here</span></span>
<span id="cb1-17"><span class="cf" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">end</span></span>
<span id="cb1-18"></span>
<span id="cb1-19">md <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> <span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Redcarpet</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">::</span><span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Markdown</span><span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.new</span>(<span class="dt" style="color: #AD0000;
background-color: null;
font-style: inherit;">Ansi</span>, <span class="wa" style="color: #5E5E5E;
background-color: null;
font-style: italic;">:fenced_code_blocks</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=&gt;</span> <span class="dv" style="color: #AD0000;
background-color: null;
font-style: inherit;">true</span>)</span>
<span id="cb1-20">md<span class="at" style="color: #657422;
background-color: null;
font-style: inherit;">.render</span>(<span class="vs" style="color: #20794D;
background-color: null;
font-style: inherit;">'Hello **markdown**\n'</span>)</span></code></pre></div>
<p>写了一个简单的 Gem，安装方法如下：</p>
<div class="sourceCode" id="cb2" style="background: #f1f3f5;"><pre class="sourceCode bash code-with-copy"><code class="sourceCode bash"><span id="cb2-1"><span class="ex" style="color: null;
background-color: null;
font-style: inherit;">$</span> gem install md2ansi</span></code></pre></div>
<p>欢迎 <a href="https://github.com/hanjianwei/md2ansi">fork</a>。</p>



 ]]></description>
  <category>WebDev</category>
  <guid>https://hanjianwei.github.io/posts/2013/04/06/markdown-to-ansi/</guid>
  <pubDate>Sat, 06 Apr 2013 12:42:00 GMT</pubDate>
</item>
<item>
  <title>C++11 和 C++98 的 ABI 兼容性</title>
  <link>https://hanjianwei.github.io/posts/2013/01/27/abi-compatibility-between-c-plus-plus-11-and-c-plus-plus-98/</link>
  <description><![CDATA[ 





<p><a href="http://en.wikipedia.org/wiki/C%2B%2B11">C++11</a> 出来已经好几年了，对其中有些特性还是很感兴趣的，比如 rvalue reference、lambda、alias templates、range-based for 等，正好最近在写 C++ 的代码，就准备尝试一下。</p>
<p>Mac OS X 下面主要的编译器是 Clang，对于 <a href="http://clang.llvm.org/cxx_status.html">C++11 的支持</a>还是很不错的。 不过 Clang 默认是用的还是 C++98 的标准，要支持 C++11 必须使用两个选项：</p>
<ul>
<li><code>-std=c++11</code>: 使用 C++11 的标准进行编译。</li>
<li><code>-stdlib=libc++</code>: 使用 libc++。libc++ 是重新实现的 C++ 标准库，对 C++11 有较好的支持。 如果不加该选项，Clang 就会是用老的 libstdc++，如果你使用了 C++11 标准库中的内容就会出错。</li>
</ul>
<p>看起来修改还是挺简单的，然后就把这两项加到我的 <code>CXXFLAGS</code> 里面，不幸的是跳出来一大堆 link error ……</p>
<p>原来我用了一些 OpenCV 之类的库，而我的库都是通过 Homebrew 安装的。Homebrew 在编译这些库的时候是用的是默认的 libstdc++，而 libc++ 和 libstdc++ 是<a href="https://github.com/mxcl/homebrew/issues/10938">不兼容</a>的，所以出现了 link error。</p>
<p>解决方法只能是重新编译 OpenCV 等库，使用 libc++。 但是这样同时也要保证 OpenCV 等依赖的那些库也是用 libc++，而依赖 OpenCV 等库的程序最好也是用 libc++，这工作量就有点太大了！——当然，如果只用 C++11 的语法而不使用库还是可以的，即只用 <code>-std=c++11</code>。</p>
<p>好吧，还是暂时放弃吧，等什么时候 <code>-std=c++11 -stdlib=libc++</code> 成为默认参数的时候再搞吧。 GCC似乎也有这种 <a href="https://gcc.gnu.org/wiki/Cxx11AbiCompatibility">C++11 和 C++98 库不兼容</a>问题，看来也不好搞:(</p>



 ]]></description>
  <category>Programming</category>
  <guid>https://hanjianwei.github.io/posts/2013/01/27/abi-compatibility-between-c-plus-plus-11-and-c-plus-plus-98/</guid>
  <pubDate>Sun, 27 Jan 2013 13:38:00 GMT</pubDate>
</item>
<item>
  <title>DocPad：基于 CoffeeScript 的静态网站生成器</title>
  <link>https://hanjianwei.github.io/posts/2013/01/06/docpad-static-site-generator-using-coffeescript/</link>
  <description><![CDATA[ 





<p><a href="http://docpad.org">DocPad</a> 是一个静态网站生成器，同 <a href="https://github.com/mojombo/jekyll">Jekyll</a>、<a href="http://octopress.org">Octopress</a> 相比，它的可定制性更强； 由于是用 <a href="http://coffeescript.org">CoffeeScript</a> 写的，速度也比以上两个快很多。最近两天玩了一下，感觉很不错：功能很强大，虽然有些插件不太稳定，但基本功能已经比较完备了。</p>
<p>几个有意思的插件：</p>
<ul>
<li><p><a href="https://github.com/docpad/docpad-plugin-marked">marked</a> 和 <a href="https://github.com/isagalaev/highlight.js">highlight.js</a>：Markdown 支持。highlight.js 是基于 Javascript 的代码高亮工具，同 Pygments 相比，它功能相对简单，但好在能和 marked 配合的比较好。DocPad 自己也有代码高亮插件，支持 Pygments，但是问题很多。下面是 highlight.js 的配置，写到 docpad.coffee 中即可：</p>
<div class="sourceCode" id="cb1" style="background: #f1f3f5;"><pre class="sourceCode coffeescript code-with-copy"><code class="sourceCode coffee"><span id="cb1-1">docpadConfig <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span></span>
<span id="cb1-2">  plugins<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb1-3">    marked<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb1-4">      markedOptions<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span></span>
<span id="cb1-5">        pedantic<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">false</span></span>
<span id="cb1-6">        gfm<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">true</span></span>
<span id="cb1-7">        sanitize<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="ot" style="color: #003B4F;
background-color: null;
font-style: inherit;">false</span></span>
<span id="cb1-8">        highlight<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="fu" style="color: #4758AB;
background-color: null;
font-style: inherit;">(code, lang) -&gt;</span></span>
<span id="cb1-9">          aliases <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span></span>
<span id="cb1-10">            html<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">:</span> <span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'xml'</span></span>
<span id="cb1-11">          lang <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> aliases<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span>lang<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span> <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">if</span> aliases<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">[</span>lang<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">]</span></span>
<span id="cb1-12"></span>
<span id="cb1-13">          hljs <span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">=</span> require<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">(</span><span class="st" style="color: #20794D;
background-color: null;
font-style: inherit;">'highlight.js'</span><span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">)</span></span>
<span id="cb1-14">          hljs<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">.</span>highlight<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">(</span>lang<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">,</span> code<span class="kw" style="color: #003B4F;
background-color: null;
font-weight: bold;
font-style: inherit;">).</span>value</span></code></pre></div></li>
<li><p><a href="https://github.com/docpad/docpad-plugin-jade">jade</a>：Jade 模板支持。</p></li>
<li><p><a href="https://github.com/docpad/docpad-plugin-paged">paged</a>：分页插件，和 <a href="https://github.com/docpad/docpad-plugin-partials">partials</a>插件有<a href="https://github.com/bevry/docpad/issues/116#issuecomment-11916419">冲突</a>，用的时候要小心点。</p></li>
<li><p><a href="https://github.com/docpad/docpad-plugin-livereload">livereload</a>：更新代码后自动刷新浏览器，酷吧:)</p></li>
</ul>
<p>DocPad 的功能非常强大，更多的功能可以去官网看看。</p>



 ]]></description>
  <category>WebDev</category>
  <guid>https://hanjianwei.github.io/posts/2013/01/06/docpad-static-site-generator-using-coffeescript/</guid>
  <pubDate>Sun, 06 Jan 2013 13:40:00 GMT</pubDate>
</item>
</channel>
</rss>
