如何为带--no-webpack参数的Phoenix项目生成assets文件夹?
--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

