You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为带--no-webpack参数的Phoenix项目生成assets文件夹?

Adding Webpack & Assets Folder to a Phoenix Project Created with --no-webpack

I’ve been in your exact spot before — copying files from a fresh Phoenix project seems like a quick fix, but version mismatches and missing dependencies usually lead to those annoying errors. Let’s build out the assets setup properly step by step:

1. Initialize npm & Install Dependencies

First, navigate to your project root in the terminal and set up npm if you haven’t already:

npm init -y

Next, install all the webpack-related tools and Phoenix’s frontend packages:

npm install --save-dev webpack webpack-cli @babel/core @babel/preset-env babel-loader css-loader style-loader sass-loader sass mini-css-extract-plugin terser-webpack-plugin
npm install phoenix phoenix_html

2. Create the Assets Folder Structure

Make the standard Phoenix assets directory tree and core files:

mkdir -p assets/js assets/css assets/static/images

Create assets/js/app.js (this is your main JS entry point):

// Import Phoenix's core frontend utilities
import "phoenix_html"

// Add your custom JavaScript code here
// Example: import "./custom_module.js"

Create assets/css/app.css (your main stylesheet):

/* Add your base styles or import SCSS files here */
body {
  margin: 0;
  padding: 2rem;
}

3. Add Webpack Configuration

Create a webpack.config.js file in your project root with this Phoenix-friendly setup (it handles development watch mode and production optimization):

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');

module.exports = (env, argv) => {
  const isProduction = argv.mode === 'production';

  return {
    entry: { app: './assets/js/app.js' },
    output: {
      filename: isProduction ? '[name].[contenthash].js' : '[name].js',
      path: path.resolve(__dirname, 'priv/static/js'),
      publicPath: '/js/'
    },
    module: {
      rules: [
        // Transpile JS with Babel
        {
          test: /\.js$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: { presets: ['@babel/preset-env'] }
          }
        },
        // Handle CSS files
        {
          test: /\.css$/,
          use: [isProduction ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader']
        },
        // Handle SCSS/SASS files
        {
          test: /\.scss$/,
          use: [isProduction ? MiniCssExtractPlugin.loader : 'style-loader', 'css-loader', 'sass-loader']
        }
      ]
    },
    plugins: [
      // Extract CSS to separate files in production
      ...(isProduction ? [new MiniCssExtractPlugin({ filename: '../css/[name].[contenthash].css' })] : [])
    ],
    optimization: {
      // Minify JS/CSS in production
      minimizer: isProduction ? [new TerserPlugin()] : []
    }
  };
};

4. Update npm Scripts & Mix Aliases

Open your package.json and add these scripts to handle webpack builds:

"scripts": {
  "watch": "webpack --watch --mode development",
  "deploy": "webpack --mode production"
}

Then open mix.exs and update the aliases section to include asset deployment (add this alongside your existing aliases):

defp aliases do
  [
    # ... your existing aliases (like "ecto.setup", "phx.server")
    "assets.deploy": ["npm run deploy", "phx.digest"]
  ]
end

5. Update Your Layout Template

Open lib/your_project_web/templates/layout/app.html.heex (replace your_project with your actual project name) and update the static asset links to point to your webpack-built files:

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- ... other meta tags, title ... -->
    <%= if Mix.env() == :prod do %>
      <link phx-track-static rel="stylesheet" href={~p"/css/app-#{Application.compile_env(:your_project, :assets_hash)}.css"} />
      <script phx-track-static defer type="text/javascript" src={~p"/js/app-#{Application.compile_env(:your_project, :assets_hash)}.js"}></script>
    <% else %>
      <link rel="stylesheet" href={~p"/css/app.css"} />
      <script defer type="text/javascript" src={~p"/js/app.js"}></script>
    <% end %>
  </head>
  <!-- ... rest of your layout ... -->
</html>

6. Test It Out

  • Start the webpack watcher in one terminal tab:
    npm run watch
    
  • Start your Phoenix server in another tab:
    mix phx.server
    
  • Visit your app in the browser — you should see your styles applied, and the JS should load without errors.

For production deployments, run mix assets.deploy to build optimized assets and generate the cache manifest.


内容的提问来源于stack exchange,提问作者Mkay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.07 13:22:46