如何在Phoenix/Elixir应用中使用Webpack

如何在Phoenix/Elixir应用中使用Webpack_第1张图片
Webpack+Phoenix

Phoenix是目前最火的后端Web框架之一,它基于Elixir,一款基于Erlang VM的语言,它有着卓越的性能和Ruby般的开发效率。而Webpack又是目前前端构建工具中冉冉升起的新星,它有着诸多非常强大的功能,几乎能提供任何你想要的前端构建流程。那我们快来看一下怎样将两者结合起来吧!

1. 初始化Phoenix应用

这里我们不用--no-brunchflag,因为使用这个flag虽然不会引入Brunch,但是会少创建一些文件夹和文件,如web/static/js等,这里我们会在创建之后把Brunch相关文件修改为Webpack的对应文件。

mix phoenix.new webpack_integration

删除brunch-config.js

rm brunch-config.js

清空Brunch相关的dependencies

{
  "repository": {
  },
  "dependencies": {
  }
}

2. 添加 Webpack

添加webpack

npm install --save-dev webpack

在项目根目录中创建webpack.config.js,并写入如下代码:

module.exports = {
  entry: "./web/static/js/app.js",
  output: {
    path: "./priv/static/js",
    filename: "app.js"
  }
};

这段代码告诉webpack找到web/static/js/app.js的内容并且编译合并到priv/static/js/app.js

我们在package.json中定义npm start脚本来运行webpack。

{
  "scripts": {
    "start": "webpack --watch-stdin --progress --color"
  }
}

在phoenix的config/dev.exs定义watchers参数,这里的意思是在mix phoenix.server服务器启动的时候运行npm start命令。

config :webpack_integration, WebpackIntegration.Endpoint,
  watchers: [npm: ["start"]]

安装phoenix和npm的所有依赖,初始化数据库,并启动服务器:

mix deps.get
npm install
mix ecto.create
mix phoenix.server

3. 增加 Babel 和 CSS 支持

安装babel依赖,这样你就可以使用JavaScript的ES2015语法。

npm install babel-loader babel-core babel-preset-es2015 --save-dev

webpack.config.js增加如下的output设置:

module.exports = {
  // entry and output options...

  module: {
    loaders: [{
      test: /\.js$/,
      exclude: /node_modules/,
      loader: "babel",
      query: {
        presets: ["es2015"]
      }
    }]
  }
}

这些规则是说应用所需的所有.js文件都通过Babel转义,一旦配置完成,重启服务器,所有Babel提供的JavaScript特性都被支持。

设置加载路径

在Webpack中使用importrequire需要明确的相对你工作目录的路径,假设你有这两个文件:

app.js
components/filePicker.js

并且我们需要在app.js中引入filePicker组件:

// Brunch
import filePicker from 'components/filePicker';

// Webpack
import filePicker from './components/filePicker';

我们可以看到Brunch和Webpack在ES2015导入/加载方面的不同。这里我们还需要告诉Webpack寻找node_modules

module.exports = {
  // Leave the entry, output, and module options we set previously

  resolve: {
    modulesDirectories: [ "node_modules", __dirname + "/web/static/js" ]
  }
}

最后一步是采用npm管理phoenix_htmlphoenix所需依赖,这些文件是通过hex安装的。

npm install file:deps/phoenix_html file:deps/phoenix --save

这样我们就可以像平常那样导入模块了:

import "phoenix_html";import { Socket } from "phoenix";

重启服务器,Phoenix JavaScript的文件就被包括在编译的文件里了。

CSS and Webpack

如果你之前使用过Webpack,你可能会看到CSS文件从独立的组件中引入。Webpack会在加载页面时内嵌css代码,而非生成单独的css文件。这里,我们只是复现Brunch的功能,我们将CSS从JavaScript中分离出去。这种处理CSS的方式和Webpack标准教程有些差异。

var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
  entry: ["./web/static/css/app.css", "./web/static/js/app.js"],
  output: {
    path: "./priv/static",
    filename: "js/app.js"
  },

  module: {
    loaders: [{
      test: /\.js$/,
      exclude: /node_modules/,
      loaders: ["babel"],
      include: __dirname,
      query: {
        presets: ["es2015"]
      }
    }, {
      test: /\.css$/,
      loader: ExtractTextPlugin.extract("style", "css")
    }]
  },

  plugins: [
    new ExtractTextPlugin("css/app.css")
  ]
};

With this configuration, webpack will grab the web/static/css/app.css
file, parse the CSS and move it to priv/static/css/app.css
. Restart your Phoenix server to see the stylesheets working. The only thing missing now are the static assets.

通过这样设置,Webpack就能够提取web/static/css/app.css并将它移动到priv/static/css/app.css。重启Phoenix服务器就能看到样式表啦。现只剩静态资源文件没有处理了。

4. 处理静态资源文件

最后,我们要移动静态资源文件使得别人能够访问它们。默认静态资源文件在web/static/assets目录下,我们需要将它们移动到priv/static下。举个例子,web/static/assets/favicon.ico会被移动到priv/static/favicon.ico

为实现这一功能,我们需要安装copy-webpack-plugin这个插件。
并且在webpack.config.js的plugins数组中添加如下:

var CopyWebpackPlugin = require("copy-webpack-plugin");

module.exports {
  // ...
  plugins: [
    new ExtractTextPlugin("css/app.css"),
    new CopyWebpackPlugin([{ from: "./web/static/assets" }])
  ]
}

添加到web/static/assets的资源文件并不自动拷贝,如果一个文件被添加,你需要重启Webpack。

5. 生产环境构建

最后一步是让webpack构建生产环境的资源文件。在package.json中添加如下代码:

{
  "scripts": {
    "compile": "webpack -p"
  }
}

现在,只需要运行npm run即可变异生产环境下的资源文件。

至此,我们已经使用Webpack替代了Brunch的所有功能。快点自己动手试试吧!如果在试验过程中遇到问题,可以看看这个repo。

扩展阅读

[1] http://manukall.de/2015/05/01/automatically-building-your-phoenix-assets-with-webpack/
[2] http://matthewlehner.net/using-webpack-with-phoenix-and-elixir/

你可能感兴趣的:(如何在Phoenix/Elixir应用中使用Webpack)