在phoenix中使用webpack

phoenix選擇了brunch做爲靜態資源的管理工具,一番折騰以後,發現這個東西確實獨特,配置少,上手簡單,編譯快。可是隨着使用的深刻,它的不足也愈來愈明顯,老舊,更新緩慢,各類資源都年久失修。爲了讓brunch配合vue使用,我甚至還花了幾天時間去修復插件vue-brunch的bug,因而,就有了本文所進行的探索。javascript

不過選擇webpack並非由於它多麼的好,偏偏相反,我反而以爲它太過複雜,概念繁多,文檔看似豐富其實猶抱琵琶。對於新手實在太不友好。不過鑑於功能和流行程度,目前處理複雜的前端資源,webpack仍是不二的選擇。css

目標

實現一個最小化的webpack配置,功能上要能徹底取代默認的brunch的配置。

webpack複雜配置的可怕你們都是有目共睹的,因此我但願這個配置能足夠精簡,僅僅完成phoenix建立項目後默認提供的那些功能就好,由於對於webpack,想擴展功能太容易了。前端

第一步

首先從assets/package.json開始,須要先卸載devDependencies下全部的包,全都換成webpack系列,命令就不列了,畢竟複製粘貼太煩人,只截取展現一下package.json吧:vue

"devDependencies": {
    "@babel/core": "^7.0.0-beta.37",
    "@babel/preset-es2015": "^7.0.0-beta.37",
    "babel-loader": "^8.0.0-beta.0",
    "copy-webpack-plugin": "^4.3.1",
    "css-loader": "^0.28.8",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.6",
    "style-loader": "^0.19.1",
    "uglifyjs-webpack-plugin": "^1.1.6",
    "webpack": "^3.10.0"
  }
這裏我激進的採用了 babel 7,相應的, babel-loader的版本須要是 8

主要部分

而後,就是最主要的webpack.config.js了,文件內容以下:java

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');

config = {
  devtool: 'eval-cheap-module-source-map',
  entry: {
    app: ['./css/app.css', './js/app.js']
  },
  output: {
    path: path.resolve(__dirname, '../priv/static'),
    filename: 'js/[name].js',
  },
  module: {
    rules: [{
        test: /\.css$/,
        use: ExtractTextPlugin.extract({
          fallback: 'style-loader',
          use: {
            loader: 'css-loader',
            options: { url: false }
          }
        })
      }, {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        options: {
          presets: ['@babel/preset-es2015']
        }
      }, {
        test: /\.(png|jpg|gif)$/,
        loader: 'file-loader',
        options: {
          name: '[path][name].[ext]'
        }
      }
    ]
  },
  plugins: [
    new ExtractTextPlugin('css/[name].css'),
    new CopyWebpackPlugin([{
      from: './static'
    }])
  ]
}

if (process.env.MIX_ENV === 'prod' || process.env.NODE_ENV === 'production') {
  config.devtool = 'source-map'
  config.plugins.concat([
    new UglifyJSPlugin({
      parallel: true,
      sourceMap: true
    }),
    new webpack.optimize.ModuleConcatenationPlugin()
  ])
}

module.exports = config

同時,還須要在./css/app.css中加上:node

@import "./phoenix.css"
能夠看到這裏使用了4個 loader,分別處理css,js和圖片三種靜態資源,
開發環境中,使用了用於提取css的 ExtractTextPlugin和用來拷貝靜態資源的 CopyWebpackPlugin
針對生產環境,增長了生成 source map的選項並使用 uglifyjs對代碼進行壓縮

須要注意的是,這裏使用了./css/app.css做爲入口之一,也就意味着沒必要在js文件中加入import來引入css文件,不過這樣一來,就須要在app.css文件中加入上面那一行代碼來解決引入css的問題。還有一種無需修改代碼的方法,即把./css/phoenix.css也加入entry中,不過我認爲這樣不夠直觀,並非一個好的選擇。webpack

依然是引入css的問題,phoenix.css中會導入一些字體文件,這些文件並不存在並且也無引入的必要,因此配置css-loader,將選項url置爲false,這樣webpack在編譯時就不會試圖檢查這些字體了。git

最後

爲了讓靜態資源在發生變化時phoenix可以及時響應,必須修改config/dev.exs,變更以下:github

-  watchers: [node: ["node_modules/brunch/bin/brunch", "watch", "--stdin",
+  watchers: [node: ["node_modules/webpack/bin/webpack.js", "--stdin", "--color",

phoenix默認配置了一些npm scripts,爲了命令行保持統一,assets/package.json相應作以下修改:web

-    "deploy": "brunch build --production",
-    "watch": "brunch watch --stdin"
+    "deploy": "MIX_ENV=prod webpack -p --progress",
+    "build": "webpack --progress",
+    "watch": "webpack --stdin --progress"
對於爲什麼不用 npm run命令來運行watcher,官方在 這裏作出瞭解釋

最後的最後,不要忘記刪除brunch-config.js,至此,就大功告成了。

附上目錄下文件的變更狀況:

deleted:    assets/brunch-config.js
    modified:   assets/css/app.css
    modified:   assets/package-lock.json
    modified:   assets/package.json
    new file:   assets/webpack.config.js
    modified:   config/dev.exs
相關文章
相關標籤/搜索