Chrome Extension in CLJS - 개발 환경 구축

17794 단어 clojurescript
머리말
  칼 갈 이 는 장작 패기 에 지장 이 없 으 며, 크롬 플러그 인 을 만 드 는 클 로 저 스 크 립 트 개발 환경 을 소개 한다.구체 적 인 도구 창고: vim (paredit, tslime, vim - clojure - static, vim - fireplace) + leiningen (lein - cljsbuild, lein - doo, lein - ancient) + com. cemerick / figgieback
시원스럽게 써 라
* 8195: 우선 cljs 를 js, 디 버 깅, 테스트 와 발표 등 으로 컴 파일 하 는 문 제 를 버 리 고 첫 번 째 중요 한 것 은 시원 하 게 쓰 는 것 입 니 다 ~ 8195: cljs 에서 가장 짜증 나 는 것 은 괄호 () 입 니 다. 과거 에 저 는 괄호 대신 문법 을 바 꿀 수 있 을 까 생각 했 습 니 다.paredit. vim 은 이 문 제 를 해결 하기에 딱 좋다.
설치 하 다.
vimrc 에 추가
Plugin 'paredit.vim'

vim 에서 실행
:source %
:PluginInstall

설정
"    
let mapleader=','
let g:mapleader=','

사용법
  • 입력 (, [, {" 은 자동 으로 생 성 ), ], }" 되 며 커서 는 그 중에서 vim 은 insert 상태 에 있다.
  • normal 모드 에서 입력 +W 하면 현재 커서 가 있 는 표현 식 을 괄호 로 감 싸 줍 니 다.
  • normal 모드 에서 입력 +w+[ 하면 현재 커서 가 있 는 표현 식 을 생 성 [] 합 니 다.
  • normal 모드 에서 입력 +w+" 하면 현재 커서 가 있 는 표현 식 을 생 성 "" 합 니 다.

  • 더 많은 용법 은 :help paredit 을 통 해 paredit 의 문 서 를 보면 됩 니 다.
    컴 파일 환경
    『 8195 』 cljs 는 js 로 컴 파일 된 후에 야 실 행 될 수 있 습 니 다. 여 기 는 leiningen 을 사용 합 니 다.셸 에서 실행
    #     
    $ lein new crx-demo
    $ cd crx-demo

    프로젝트 디 렉 터 리 의 project.clj 는 바로 프로젝트 파일 입 니 다. 우 리 는 이 를 다음 과 같이 수정 합 니 다.
    (defproject crx-demo "0.1.0-SNAPSHOT"
      :description "crx-demo"
      :urnl "http://fsjohnhuang.cnblogs.com"
      :license {:name "Eclipse Public License"
                :url "http://www.eclipse.org/legal/epl-v10.html"}
      :dependencies [[org.clojure/clojure "1.8.0"]               ;;   dependencies       
                     [org.clojure/clojurescript "1.9.908"]]
      :plugins [[lein-cljsbuild "1.1.7"]]                        ;;   plugins  leiningen   ,       lein cljsbuild  lein-cljsbuild     
      :jvm-opts ["-Xmx1g"]                                        ;;   JVM    ,            
      :cljsbuild {:builds
                  [{:id "browser_action"
                    :source-paths ["src/browser_action"]
                    :compiler {:main browser-action.core
                               :output-to "resources/public/browser_action/js/ignoreme.js"
                               :output-dir "resources/public/browser_action/js/out"
                               :asset-path "browser_action/js/out"
                               :optimizations :none              ;;   :       ,         :none
                               :source-map true
                               :source-map-timestamp true}}
                   {:id "content_scripts"
                    :source-paths ["src/content_scripts"]
                    :compiler {:main content-scripts.core
                               :output-to "resources/public/content_scripts/js/content_scripts.js"
                               :output-dir "resources/public/content_scripts/js/out"
                               :asset-path "content_scripts/js/out"
                               :optimizations :whitespace
                               :source-map true
                               :source-map-timestamp true}}}]}
      :aliases {"build" ["cljsbuild" "auto" "browser_action" "content_scripts"] ;;     ,    lein build       browser_action content_scripts      。
      })

      위 설정 은 분명 합 니 다. 저 는 browseraction 과 contentscripts 는 두 개의 독립 된 하위 항목 으로 크롬 플러그 인 에서 Browser Action, Page Action, Content Scripts 와 Background 등 은 모두 상대 적 으로 독립 된 모듈 이 서로 의존 하지 않 고 실행 방식 과 환경 이 다 르 기 때문에 독립 된 하위 항목 으로 설정, 컴 파일 과 최적화 가 더욱 적합 합 니 다.다음 에 resources / public / img 디 렉 터 리 를 새로 만 들 고 icon. jpg 라 는 아이콘 을 첨부 하면 됩 니 다.esmp;그리고 resources / public 에서 manifest. json 파일 을 새로 만 듭 니 다. 수정 내용 은 다음 과 같 습 니 다.
    {
      "manifest_version": 2,
      "name": "crx-demo",
      "version": "1.0.0",
      "description": "crx-demo",
      "icons":
      {
        "16": "img/icon.jpg",
        "48": "img/icon.jpg",
        "128": "img/icon.jpg"
      },
      "browser_action":
      {
        "default_icon": "img/icon.jpg",
        "default_title": "crx-demo",
        "default_popup": "browser_action.html"
      },
      "content_scripts":
      [
            {
                "matches": ["*://*/*"],
                "js": ["content_scripts/js/core.js"],
                "run_at": "document_start"
            }
      ],
      "permissions": ["tabs", "storage"]
    }

    다음 에 새로 만 들 기 resources/public/browser_action.html, 그리고 수정 내용 은 다음 과 같 습 니 다.
    
    
    
      
      
    
    
      <script src="browser_action/js/out/goog/base.js"/>
      <script src="browser_action/js/out/goog/deps.js"/>
      <script src="browser_action/js/out/cljs_deps.js"/>
      <script src="browser_action.js"/>
    
    </code></pre> 
     <p>             <code>browser_action.js</code> ?    ,     Browser Action      google closure compiler        。</p> 
     <h3>Browser Action/Popup    </h3> 
     <p>       ,  <code>default_popup</code>              , <code>optimizations :none</code> google closure compiler        <code>ignoreme.js</code> </p> 
     <pre><code>var CLOSURE_UNCOMPILED_DEFINES = {};
    var CLOSURE_NO_DEPS = true;
    if(typeof goog == "undefined") document.write('<script src="resources/public/browser_action/js/out/goog/base.js"/>');
    document.write('<script src="resources/public/browser_action/js/out/goog/deps.js"/>');
    document.write('<script src="resources/public/browser_action/js/out/cljs_deps.js"/>');
    document.write('<script>if (typeof goog == "undefined") console.warn("ClojureScript could not load :main, did you forget to specify :asset-path?");</script>');
    document.write('<script>goog.require("process.env");</script>');
    document.write('<script>goog.require("crx_demo.core");</script>');</code></pre> 
     <p>             ~~~           ,    <code>resources/public/browser_action.js</code>,        </p> 
     <pre><code>goog.require("process.env")
    goog.require("crx_demo.core")</code></pre> 
     <p>       Browser Action/Popup        ^_^。       <code>goog.require("crx_demo.core")</code>    ?           <code>crx-demo.core</code> ?   ,        <code>-</code>   <code>_</code>,  goog             <code>-</code>   <code>_</code>。</p> 
     <h3>Content Scripts    </h3> 
     <p>   content scripts       ,        popup             ,      <code>optimizations :whitespace</code>          js   。              ~  ~ ~~~</p> 
     <h2>    </h2> 
     <p>              cljs,       。  ,           ,         API DOC,          ?</p> 
     <h3> vim   API DOC</h3> 
     <p>   vim-fireplace       vim,  API  ,          !<br/>1. vim  </p> 
     <pre><code>Plugin 'tpope/vim-fireplace'</code></pre> 
     <p> vim   </p> 
     <pre><code>:source %
    :PluginInstall</code></pre> 
     <p>2.  nRepl   piggieback<br/> nRepl    repl,          ,             。      <code>lein repl</code>  Clojure nRepl。<br/>  fireplace     vim   nRepl    ,         Clojure nRepl,          cljs nRepl。       project.clj       。</p> 
     <pre><code>:dependencies [[com.cemerick/piggieback "0.2.2"]]
    :repl-options {:port 9000
                   :nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}</code></pre> 
     <p>  shell     <code>lein deps</code><br/>3.  fireplace    <br/>           ,<code>echo 9000 > .nreplport</code><br/>4.  nRepl,<code>lein repl</code><br/>    vim   <code>:Source map</code>    <code>cljs.core/map</code>   ,         :</p> 
     <pre><code>:Connect
    Protocol: nrepl
    Host: localhost
    Port: 9000
    Scope connection to: ~/crx-dome</code></pre> 
     <p>      fireplace nrepl     。<br/>5.     <br/>              fireplace        ,   <code>:Source <symbol/></code>    ,<code>:FindDoc <keyword/></code>     Docstring,     <code>:Doc <symbol/></code>       Docstring。<br/>       <code>:Source <symbol/></code>          ,  <code>lein build</code>      ,      。            , <code>optimizations</code>  <code>:none</code>            fireplace    ,     Content Scrpts       ~~~</p> 
     <p>          ?   tslime.vim    !</p> 
     <h3>tslime.vim</h3> 
     <p> tslime.vim           vim         repl   <br/>1.  vim  </p> 
     <pre><code>Plugin 'jgdavey/tslime.vim'</code></pre> 
     <p> vim   </p> 
     <pre><code>:source %
    :PluginInstall</code></pre> 
     <p>2..vimrc  </p> 
     <pre><code>"             tmux   session   window 
    let g:tslime_always_current_session = 1 let g:tslime_always_current_window = 1
    
    vmap <c-c><c-c> <plug>SendSelectionToTmux
    nmap <c-c><c-c> <plug>NormalModeSendToTmux
    nmap <c-c>r <plug>SetTmuxVars</plug></c-c></plug></c-c></c-c></plug></c-c></c-c></code></pre> 
     <p>3. clojure repl  cljs repl<br/>   <code>lein repl</code>       cljs nrepl fireplace  ,             clojure repl, tslime            repl。        clojure repl   <code>(cemerick.piggieback/cljs-repl (cljs.repl.rhino/repl-env))</code>  。<br/>      vim               <code><c-c><c-c/></c-c></code>,                repl    。</p> 
     <h2>    </h2> 
     <p>   cljs   js         ,                console  ,          。              ,   devtools                     (    !)<br/> project.clj   </p> 
     <pre><code>:dependencies [[binaryage/devtools "0.9.4"]]
    ;;         compiler   
    :compiler {:preloads [devtools.preload]
               :external-config {:devtools/config {:features-to-install [:formatters :hints :async]}}}</code></pre> 
     <p>        <code>js/console.log</code>、<code>js/console.info</code>              。</p> 
     <h2>       </h2> 
     <p>          ,         ? project.clj   </p> 
     <pre><code>:plugins [[lein-doo "0.1.7"]]</code></pre> 
     <p>   <code>test/crx_demo</code>     runner.cljs  ,       </p> 
     <pre><code>(ns crx-demo.runner
      (:require-macros [doo.runners :refer [doo-tests]])
      (:require [crx-demo.content-scripts.util-test]))
    
    ;;       crx-demo.content-scripts.util         ,        crx-demo.content-scripts.util-test 
    (doo-tests 'crx-demo.content-scripts.util-test)</code></pre> 
     <p>    crx-demo.content-scripts.util-test.cljs      </p> 
     <pre><code>(ns crx-demo.content-scripts.util-test
      (:require-macros [cljs.test :refer [deftest is are testing async]]
      (:require [crx-demo.content-scripts.util :as u]))
    
    (deftest test-all-upper-case?
      (testing "all-upper-case?"
        (are [x] (true? x)
          (u/all-upper-case? "abCd")
          (u/all-upper-case? "ABCD"))))
    
    (deftest test-all-lower-case?
      (testing "all-lower-case?"
        (is (true? (u/all-lower-case? "cinG")))))
    
    (deftest test-get-async
      (async done
        (u/get-async (fn [item]
                       (is (seq item))
                       (done)))))</code></pre> 
     <p>              </p> 
     <pre><code>{:id "test-proj"
     :source-paths ["src/content_scripts" "test/crx_demo"]
     :compiler {:target :nodejs                   ;;       nodejs
                :main crx-demo.runner
                :output-to "out/test.js"
                :output-dir "out/out"
                :optimizations :none
                :source-map true
                :source-map-timestamp true}}</code></pre> 
     <p>   shell   <code>lein doo node test-proj</code></p> 
     <h2>     externs</h2> 
     <p>         <code>optimizations</code>   <code>advanced</code>     ,                </p> 
     <pre><code>Uncaught TypeError: sa.B is not a function</code></pre> 
     <p>         ?<br/>        <code>optimizations</code>   <code>simple</code>,           ,   <code>chrome.runtime.onMessage.addListener</code>              。   <code>advanced</code>     ,                GCC     ,  GCC            ,           ,                       。Cljs            ,     extern  ,extern         、     ,  GCC  extern                      。<br/>  :chrome extern  chrome.js  </p> 
     <pre><code>/**
     * @constructor
     */
    function MessageSender(){}
    /** @type {!Tab|undefined} */
    MessageSender.prototype.tab</code></pre> 
     <h3>  </h3> 
     <p>1.  https://github.com/google/closure-compiler/tree/master/contrib/externs, chrome.js chrome_extensions.js       externs   <br/>2.  project.clj  </p> 
     <pre><code>:compiler {:externs ["externs/chrome.js" "externs/chrome_extensions.js"]}</code></pre> 
     <h2>  </h2> 
     <p>     project.clj </p> 
     <pre><code>(defproject crx-demo "0.1.0-SNAPSHOT"
      :description "crx-demo"
      :urnl "http://fsjohnhuang.cnblogs.com"
      :license {:name "Eclipse Public License"
                :url "http://www.eclipse.org/legal/epl-v10.html"}
      :dependencies [[org.clojure/clojure "1.8.0"]
                     [org.clojure/clojurescript "1.9.908"]
                     [binaryage/devtools "0.9.4"]
                     [com.cemerick/piggieback "0.2.2"]]
      :plugins [[lein-cljsbuild "1.1.7"]
                [lein-doo "0.1.7"]
                [lein-ancient "0.6.12"]] ;;   `lein ancient upgrade`   `lein ancient upgrade:plugins`     
      :clean-targets ^{:protect false} [:target-path "out" "resources/public/background" "resources/public/content_scripts" "resources/public/browser_action"]
      :jvm-opts ["-Xmx1g"]
      :repl-options {:port 9000
                     :nrepl-middleware [cemerick.piggieback/wrap-cljs-repl]}
      :cljsbuild {:builds
                  [{:id "browser_action"
                    :source-paths ["src/browser_action"]
                    :compiler {:main browser-action.core
                               :output-to "resources/public/browser_action/js/ignoreme.js"
                               :output-dir "resources/public/browser_action/js/out"
                               :asset-path "browser_action/js/out"
                               :optimizations :none
                               :source-map true
                               :source-map-timestamp true
                               :externs ["externs/chrome.js" "externs/chrome_extensions.js"]
                               :preloads [devtools.preload]
                               :external-config {:devtools/config {:features-to-install [:formatters :hints :async]}}}}
                   {:id "content_scripts"
                    :source-paths ["src/content_scripts"]
                    :compiler {:main content-scripts.core
                               :output-to "resources/public/content_scripts/js/content_scripts.js"
                               :output-dir "resources/public/content_scripts/js/out"
                               :asset-path "content_scripts/js/out"
                               :optimizations :whitespace
                               :source-map true
                               :source-map-timestamp true
                               :externs ["externs/chrome.js" "externs/chrome_extensions.js"]
                               :preloads [devtools.preload]
                               :external-config {:devtools/config {:features-to-install [:formatters :hints :async]}}}}]}
      :aliases {"build" ["cljsbuild" "auto" "browser_action" "content_scripts"]
                "test"  ["doo" "node" "test-proj"]})</code></pre> 
     <p>   cljs      ,          ^_^<br/>    ,       :http://www.cnblogs.com/fsjohn... ^_^  John</p> 
     <h2>  </h2> 
     <p>http://astashov.github.io/blo...<br/>https://github.com/emezeske/l...<br/>https://nvbn.github.io/2014/1...<br/>https://github.com/binaryage/...<br/>https://clojurescript.org/too...<br/>https://github.com/google/clo...</p> 
    </div>
                                </div>
                            </div>

    좋은 웹페이지 즐겨찾기