探索vue-cli的webpack和webpack-simple模板的development server實現差別

之前初始化 vue工程都是用的 webapck的完整配置模板,即:
vue init webpack my-project
最近寫一個簡單的 vue組件,準備發佈到 npm,所以決定使用更簡潔的 webapck配置模板,即:
vue init webpack-simple my-project
初始化完成後,發現 index.html中多了對 build.js的引用,而 webapck的完整配置模板中的 index.html是沒有對輸出文件 build.js的引用的,這引發個人注意,決定看看爲什麼有這樣的差別。

HtmlWebpackPlugin

最開始我認爲完整版的webapck配置中使用了html-webpack-plugin插件,該插件會以index.html爲模板,注入引用build.js<script src="/dist/build.js"></script>標籤,所以不須要手動在index.html中引用build.js。所以我在簡潔版webapck配置中添加了html-webpack-plugin插件,並刪除index.html中對build.js的引用,發現並不生效。html

plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      template: 'index.html',
      inject: true
    })
  ]

webpack-dev-server

查閱webpack-dev-server文檔,發現有這樣的描述:vue

It will not be written to your configured output directory. Where a bundle already exists at the same URL path, the bundle in memory takes precedence (by default).

大概意思是說,webpack-dev-server不會把打包出的文件寫入硬盤,而是把打包文件保存在內存中,而且優先返回內存中的內容。根據這段描述,我執行npm run dev啓動了服務器(端口8080),打開http://localhost:8080,能夠正常訪問。這時,個人工程中是沒有dist文件夾的,打開http://localhost:8080/dist也能夠正常訪問;說明webpack-dev-server確實在內存中保存着輸出文件,在瀏覽器請求時,webpack-dev-server返回了內存中的內容。
這下能夠理解了,啓動服務器後,打開http://localhost:8080,瀏覽器會默認去加載根目錄下的index.html,而後再根據<script src="/dist/build.js"></script>標籤去請求build.jswebpack-dev-server返回了內存中的build.js(這個時候,硬盤上並不存在build.js)。
若是index.html不引用build.js,瀏覽器就不會去請求build.js,頁面不能正常顯示。若是不想在index.html引用打包後的文件(好比每次打包文件名都是隨機的),可使用html-webpack-harddisk-pluginhtml-webpack-plugin使webpack-dev-server具備向硬盤文件(index.html)注入script標籤的能力,也能夠在使用html-webpack-plugin的前提下將npm run dev執行的命令修改成:java

webpack --config webpack.config.js && webpack-dev-server --open --hot --content-base ./build

即先讓webpack編譯再讓服務器返回編譯結果,事實上vue-cli的完整版webpack配置模板就是這樣作的。webpack

vue-cli的完整webpack配置模板中的development server實現

根據上面的分析,簡潔版webpack配置中必須在index.html中引用build.js,頁面才能正常顯示,但爲何完整webpack配置模板不須要引入呢。
經過查看完整webpack配置模板中的./build/dev-server.js能夠看到,其實在完整版中vue-cli是本身用expresswebpack-dev-middlewarewebpack-hot-middleware等實現的development server,而不是用的webpack-dev-serverwebpack-dev-middleware使用webpack編譯源文件並將結果保存在內存中,在瀏覽器請求資源時,返回內存中的內容;而且該模板中是使用了html-webpack-plugin的,在編譯的時候已經在index.html中注入了build.js的引用,所以不須要事先在index.html寫好build.js的引用。git

總結

  • webpack-dev-server不具有向硬盤文件(index.html)注入script標籤的能力,只能事先在index.html中寫好對build.js的引用。
  • vue-cli的完整webpack配置模板,採用的策略是用webpack-dev-middleware先編譯源文件並保存在內存中(使用html-webpack-plugin注入js引用),再返回給瀏覽器。
  • vue-cli的完整webpack配置模板是基於express構建的服務器,沒有使用webpack-dev-server

其它

在開發的過程當中,我發現vue-cli的簡潔webpack配置模板在開發模式下,不會把es6語法轉換爲es5語法,而執行打包操做時卻會轉換。vue-cli的完整webpack配置模板不存在這個問題。
webpack-dev-server的issues中,有人說,因爲是在命令行啓動、配置的webpack-dev-serverwebpack會到全局查找babel配置,本地的babel不生效,從而致使語法轉換失敗。
我我的並無找到確切緣由,望知情人指點。es6

相關文章
相關標籤/搜索