升级到 Webpack 5 后如何阻止 webpack 创建 dist/main.js?
How to stop webpack from creating dist/main.js after upgrade to Webpack 5?
我在 Elixir/Phoenix 中使用 Webpack。我最近从 Webpack 4 升级到了 Webpack 5。
我认为一切正常,除了现在由于某种原因,当我 运行 我的测试时,总是在项目根目录 dist/main.js
创建一个 dist 和 main.js。此文件大部分是空的:
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/
/******/
/******/ })()
;
在我的 mix.exs 中,我有以下内容。这是创建 dist/main.js
的代码行
defp compile_assets(_) do
Mix.shell().cmd("./assets/node_modules/webpack/bin/webpack.js --mode development",
quiet: false
)
end
我的 webpack.config 包括:
devtool: 'eval-source-map',
entry: {
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js']),
'marketing': glob.sync('./vendor/**/*.js').concat(['./js/marketing.js']),
'admin': glob.sync('./vendor/**/*.js').concat(['./js/admin.js']),
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../priv/static/js')
},
当我在 IEx 中 运行 这个时,我得到:
iex(1)> Mix.shell().cmd("./assets/node_modules/webpack/bin/webpack.js --mode development", quiet: false)
asset main.js 662 bytes [emitted] (name: main)
ERROR in main
Module not found: Error: Can't resolve './src' in '/Users/me/development/apps/my_app'
resolve './src' in '/Users/me/development/apps/my_app'
No description file found in /Users/me/development/apps/my_app or above
No description file found in /Users/me/development/apps/my_app or above
no extension
/Users/me/development/apps/my_app/src doesn't exist
.js
/Users/me/development/apps/my_app/src.js doesn't exist
.json
/Users/me/development/apps/my_app/src.json doesn't exist
.wasm
/Users/me/development/apps/my_app/src.wasm doesn't exist
as directory
/Users/me/development/apps/my_app/src doesn't exist
webpack 5.50.0 compiled with 1 error in 50 ms
1
因为我已经指定了条目,所以我认为它应该没问题。任何帮助将不胜感激。
更新:
显示整个 webpack.config.js
const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
const webpack = require('webpack')
const Dotenv = require('dotenv-webpack');
module.exports = (webpackEnv, webpackOptions) => {
const platform = process.env.PLATFORM
if (platform == undefined) {
throw "process.env.PLATFORM is undefined!"
}
dotEnvFile = `.env.${platform}`
const mode = platform === 'production' ? 'production' : 'development';
const minimize = platform === 'production' ? true : false;
const cache = platform === 'production' ? false : { type: 'filesystem' };
const vueProdDevtools = platform === 'production' ? false : true;
return {
cache: cache,
mode: mode,
optimization: {
minimize: minimize,
minimizer: [
new TerserPlugin({
parallel: true
}),
new CssMinimizerPlugin()
]
},
entry: {
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js']),
'marketing': glob.sync('./vendor/**/*.js').concat(['./js/marketing.js']),
'admin': glob.sync('./vendor/**/*.js').concat(['./js/admin.js']),
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../priv/static/js')
},
module: {
rules: [
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader',
options: {
compilerOptions: {
compatConfig: {
MODE: 2
}
}
}
}
]
}, {
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}
]
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
plugins: [
new Dotenv({
path: path.resolve(__dirname, '..', dotEnvFile)
}),
new MiniCssExtractPlugin({ filename: '../css/[name].css' }),
new CopyWebpackPlugin({patterns:[{ from: 'static/', to: '../' }]}),
new VueLoaderPlugin(),
new webpack.DefinePlugin({
__VUE_PROD_DEVTOOLS__: vueProdDevtools
})
],
resolve: {
alias: {
vue: '@vue/compat'
},
extensions: [ '*', '.js', '.vue', '.json' ],
},
}
};
更新 2:
根据将文件名转换为函数的建议,我将其更新为:
output: {
filename: (pathData, assetInfo) => {
console.log("******** pathData:", pathData)
console.log("******** assetInfo:", assetInfo)
return '[name].js'
},
path: path.resolve(__dirname, '../priv/static/js')
}
有趣的是当我 运行
mix phx.server
输出是:
******** pathData: {
hash: '449eeaf77670741a6887',
runtime: 'app',
chunk: Chunk {
id: 'app',
ids: [ 'app' ],
debugId: 1000,
name: 'app',
idNameHints: SortableSet [Set] {
_sortFn: undefined,
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
preventIntegration: false,
filenameTemplate: undefined,
_groups: SortableSet [Set] {
[Entrypoint],
_sortFn: [Function: compareChunkGroupsByIndex],
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
runtime: 'app',
files: SetDeprecatedArray [Set] { '../css/app.css' },
auxiliaryFiles: Set {},
rendered: false,
hash: '09da590258e85092531ee1a26f184db4',
contentHash: [Object: null prototype] {
'css/mini-extract': '4500f8bd1df6d9d548c3',
javascript: 'a1a060a5ddfcebc58653'
},
renderedHash: '09da590258e85092531e',
chunkReason: undefined,
extraAsync: false
},
contentHashType: 'javascript'
}
******** assetInfo: {}
******** pathData: {
hash: '449eeaf77670741a6887',
runtime: 'marketing',
chunk: Chunk {
id: 'marketing',
ids: [ 'marketing' ],
debugId: 1001,
name: 'marketing',
idNameHints: SortableSet [Set] {
_sortFn: undefined,
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
preventIntegration: false,
filenameTemplate: undefined,
_groups: SortableSet [Set] {
[Entrypoint],
_sortFn: [Function: compareChunkGroupsByIndex],
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
runtime: 'marketing',
files: SetDeprecatedArray [Set] { '../css/marketing.css' },
auxiliaryFiles: Set {},
rendered: false,
hash: 'e11f89b04d9e2d62877069c780bfd99c',
contentHash: [Object: null prototype] {
'css/mini-extract': '1218451d2cf9d01e4c35',
javascript: '0bf8255fc0482a761bba'
},
renderedHash: 'e11f89b04d9e2d628770',
chunkReason: undefined,
extraAsync: false
},
contentHashType: 'javascript'
}
******** assetInfo: {}
******** pathData: {
hash: '449eeaf77670741a6887',
runtime: 'admin',
chunk: Chunk {
id: 'admin',
ids: [ 'admin' ],
debugId: 1002,
name: 'admin',
idNameHints: SortableSet [Set] {
_sortFn: undefined,
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
preventIntegration: false,
filenameTemplate: undefined,
_groups: SortableSet [Set] {
[Entrypoint],
_sortFn: [Function: compareChunkGroupsByIndex],
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
runtime: 'admin',
files: SetDeprecatedArray [Set] { '../css/admin.css' },
auxiliaryFiles: Set {},
rendered: false,
hash: '6a55d7e6d1cc37be6087e1c464285cc2',
contentHash: [Object: null prototype] {
'css/mini-extract': '613df220ea4099b5fbf5',
javascript: '90a7803cefe86244fd07'
},
renderedHash: '6a55d7e6d1cc37be6087',
chunkReason: undefined,
extraAsync: false
},
contentHashType: 'javascript'
}
******** assetInfo: {}
所以,我看到每个入口点 运行 一次(有道理)。然而,当我在 IEx 中时:
Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Mix.shell().cmd("./assets/node_modules/webpack/bin/webpack.js --mode development", quiet: false)
asset main.js 662 bytes [compared for emit] (name: main)
ERROR in main
Module not found: Error: Can't resolve './src' in '/Users/me/development/apps/my_app'
resolve './src' in '/Users/me/development/apps/my_app'
No description file found in /Users/me/development/apps/my_app or above
No description file found in /Users/me/development/apps/my_app or above
no extension
/Users/me/development/apps/my_app/src doesn't exist
.js
/Users/me/development/apps/my_app/src.js doesn't exist
.json
/Users/me/development/apps/my_app/src.json doesn't exist
.wasm
/Users/me/development/apps/my_app/src.wasm doesn't exist
as directory
/Users/me/development/apps/my_app/src doesn't exist
webpack 5.51.1 compiled with 1 error in 47 ms
1
因此 console.log
命令未在 IEx 中打印。会不会有关系?可能是测试代码是 运行ning 的命令,IEx 中的 运行ning 是一个“不同的”webpack 命令吗?是不是找不到 webpack.config?
创建 dist/main.js 的原因是当 webpack 运行 时它无法找到 webpack.config.js 所以 dist/main.js 是默认行为.
我在将 filename
更新为函数时发现了这一点。然后我在其中调用 console.log("test")
并希望在 IEx 中看到它。控制台日志从未打印出来。
然后我 运行 常规 mix phx.server
我确实得到了新的输出。
在 dev.exs
中有:
watchers: [
node: [
"node_modules/webpack/bin/webpack.js",
"--mode",
"development",
"--progress",
"--watch",
"--watch-options-stdin",
cd: Path.expand("../assets", __DIR__)
]
]
这一切看起来都符合预期,但实现方式不同。 (它正在使用 cd: Path.expand
但我现在才注意到这一点。)
那么,为什么一个不工作而另一个很好呢?
细看时
defp compile_assets(_) do
Mix.shell().cmd("./assets/node_modules/webpack/bin/webpack.js --mode development",
quiet: false
)
end
我决定看看我是从哪里得到这个的(来自 Wallaby 文档)
我返回文档并注意到它已更改。
更改如下:
https://github.com/elixir-wallaby/wallaby/commit/834bdb726228349f800837e470a0c77cd2f4a6bd
现在代码应该是:
defp compile_assets(_) do
Mix.shell().cmd("cd assets && ./node_modules/.bin/webpack --mode development",
quiet: true
)
我不知道为什么我们需要 cd 到资产而不是我们以前拥有的资产,但现在可以了。
我在 Elixir/Phoenix 中使用 Webpack。我最近从 Webpack 4 升级到了 Webpack 5。
我认为一切正常,除了现在由于某种原因,当我 运行 我的测试时,总是在项目根目录 dist/main.js
创建一个 dist 和 main.js。此文件大部分是空的:
/*
* ATTENTION: The "eval" devtool has been used (maybe by default in mode: "development").
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
/******/ (() => { // webpackBootstrap
/******/ "use strict";
/******/
/******/
/******/ })()
;
在我的 mix.exs 中,我有以下内容。这是创建 dist/main.js
defp compile_assets(_) do
Mix.shell().cmd("./assets/node_modules/webpack/bin/webpack.js --mode development",
quiet: false
)
end
我的 webpack.config 包括:
devtool: 'eval-source-map',
entry: {
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js']),
'marketing': glob.sync('./vendor/**/*.js').concat(['./js/marketing.js']),
'admin': glob.sync('./vendor/**/*.js').concat(['./js/admin.js']),
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../priv/static/js')
},
当我在 IEx 中 运行 这个时,我得到:
iex(1)> Mix.shell().cmd("./assets/node_modules/webpack/bin/webpack.js --mode development", quiet: false)
asset main.js 662 bytes [emitted] (name: main)
ERROR in main
Module not found: Error: Can't resolve './src' in '/Users/me/development/apps/my_app'
resolve './src' in '/Users/me/development/apps/my_app'
No description file found in /Users/me/development/apps/my_app or above
No description file found in /Users/me/development/apps/my_app or above
no extension
/Users/me/development/apps/my_app/src doesn't exist
.js
/Users/me/development/apps/my_app/src.js doesn't exist
.json
/Users/me/development/apps/my_app/src.json doesn't exist
.wasm
/Users/me/development/apps/my_app/src.wasm doesn't exist
as directory
/Users/me/development/apps/my_app/src doesn't exist
webpack 5.50.0 compiled with 1 error in 50 ms
1
因为我已经指定了条目,所以我认为它应该没问题。任何帮助将不胜感激。
更新: 显示整个 webpack.config.js
const path = require('path');
const glob = require('glob');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const CssMinimizerPlugin = require("css-minimizer-webpack-plugin");
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { VueLoaderPlugin } = require('vue-loader');
const webpack = require('webpack')
const Dotenv = require('dotenv-webpack');
module.exports = (webpackEnv, webpackOptions) => {
const platform = process.env.PLATFORM
if (platform == undefined) {
throw "process.env.PLATFORM is undefined!"
}
dotEnvFile = `.env.${platform}`
const mode = platform === 'production' ? 'production' : 'development';
const minimize = platform === 'production' ? true : false;
const cache = platform === 'production' ? false : { type: 'filesystem' };
const vueProdDevtools = platform === 'production' ? false : true;
return {
cache: cache,
mode: mode,
optimization: {
minimize: minimize,
minimizer: [
new TerserPlugin({
parallel: true
}),
new CssMinimizerPlugin()
]
},
entry: {
'app': glob.sync('./vendor/**/*.js').concat(['./js/app.js']),
'marketing': glob.sync('./vendor/**/*.js').concat(['./js/marketing.js']),
'admin': glob.sync('./vendor/**/*.js').concat(['./js/admin.js']),
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, '../priv/static/js')
},
module: {
rules: [
{
test: /\.vue$/,
use: [
{
loader: 'vue-loader',
options: {
compilerOptions: {
compatConfig: {
MODE: 2
}
}
}
}
]
}, {
test: /\.js$/,
exclude: /node_modules/,
use: [
{
loader: 'babel-loader'
}
]
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
'css-loader',
'postcss-loader'
]
},
{
test: /\.scss$/,
use: [
'vue-style-loader',
'css-loader',
'sass-loader'
]
}
]
},
plugins: [
new Dotenv({
path: path.resolve(__dirname, '..', dotEnvFile)
}),
new MiniCssExtractPlugin({ filename: '../css/[name].css' }),
new CopyWebpackPlugin({patterns:[{ from: 'static/', to: '../' }]}),
new VueLoaderPlugin(),
new webpack.DefinePlugin({
__VUE_PROD_DEVTOOLS__: vueProdDevtools
})
],
resolve: {
alias: {
vue: '@vue/compat'
},
extensions: [ '*', '.js', '.vue', '.json' ],
},
}
};
更新 2:
根据将文件名转换为函数的建议,我将其更新为:
output: {
filename: (pathData, assetInfo) => {
console.log("******** pathData:", pathData)
console.log("******** assetInfo:", assetInfo)
return '[name].js'
},
path: path.resolve(__dirname, '../priv/static/js')
}
有趣的是当我 运行
mix phx.server
输出是:
******** pathData: {
hash: '449eeaf77670741a6887',
runtime: 'app',
chunk: Chunk {
id: 'app',
ids: [ 'app' ],
debugId: 1000,
name: 'app',
idNameHints: SortableSet [Set] {
_sortFn: undefined,
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
preventIntegration: false,
filenameTemplate: undefined,
_groups: SortableSet [Set] {
[Entrypoint],
_sortFn: [Function: compareChunkGroupsByIndex],
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
runtime: 'app',
files: SetDeprecatedArray [Set] { '../css/app.css' },
auxiliaryFiles: Set {},
rendered: false,
hash: '09da590258e85092531ee1a26f184db4',
contentHash: [Object: null prototype] {
'css/mini-extract': '4500f8bd1df6d9d548c3',
javascript: 'a1a060a5ddfcebc58653'
},
renderedHash: '09da590258e85092531e',
chunkReason: undefined,
extraAsync: false
},
contentHashType: 'javascript'
}
******** assetInfo: {}
******** pathData: {
hash: '449eeaf77670741a6887',
runtime: 'marketing',
chunk: Chunk {
id: 'marketing',
ids: [ 'marketing' ],
debugId: 1001,
name: 'marketing',
idNameHints: SortableSet [Set] {
_sortFn: undefined,
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
preventIntegration: false,
filenameTemplate: undefined,
_groups: SortableSet [Set] {
[Entrypoint],
_sortFn: [Function: compareChunkGroupsByIndex],
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
runtime: 'marketing',
files: SetDeprecatedArray [Set] { '../css/marketing.css' },
auxiliaryFiles: Set {},
rendered: false,
hash: 'e11f89b04d9e2d62877069c780bfd99c',
contentHash: [Object: null prototype] {
'css/mini-extract': '1218451d2cf9d01e4c35',
javascript: '0bf8255fc0482a761bba'
},
renderedHash: 'e11f89b04d9e2d628770',
chunkReason: undefined,
extraAsync: false
},
contentHashType: 'javascript'
}
******** assetInfo: {}
******** pathData: {
hash: '449eeaf77670741a6887',
runtime: 'admin',
chunk: Chunk {
id: 'admin',
ids: [ 'admin' ],
debugId: 1002,
name: 'admin',
idNameHints: SortableSet [Set] {
_sortFn: undefined,
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
preventIntegration: false,
filenameTemplate: undefined,
_groups: SortableSet [Set] {
[Entrypoint],
_sortFn: [Function: compareChunkGroupsByIndex],
_lastActiveSortFn: Symbol(not sorted),
_cache: undefined,
_cacheOrderIndependent: undefined
},
runtime: 'admin',
files: SetDeprecatedArray [Set] { '../css/admin.css' },
auxiliaryFiles: Set {},
rendered: false,
hash: '6a55d7e6d1cc37be6087e1c464285cc2',
contentHash: [Object: null prototype] {
'css/mini-extract': '613df220ea4099b5fbf5',
javascript: '90a7803cefe86244fd07'
},
renderedHash: '6a55d7e6d1cc37be6087',
chunkReason: undefined,
extraAsync: false
},
contentHashType: 'javascript'
}
******** assetInfo: {}
所以,我看到每个入口点 运行 一次(有道理)。然而,当我在 IEx 中时:
Interactive Elixir (1.12.2) - press Ctrl+C to exit (type h() ENTER for help)
iex(1)> Mix.shell().cmd("./assets/node_modules/webpack/bin/webpack.js --mode development", quiet: false)
asset main.js 662 bytes [compared for emit] (name: main)
ERROR in main
Module not found: Error: Can't resolve './src' in '/Users/me/development/apps/my_app'
resolve './src' in '/Users/me/development/apps/my_app'
No description file found in /Users/me/development/apps/my_app or above
No description file found in /Users/me/development/apps/my_app or above
no extension
/Users/me/development/apps/my_app/src doesn't exist
.js
/Users/me/development/apps/my_app/src.js doesn't exist
.json
/Users/me/development/apps/my_app/src.json doesn't exist
.wasm
/Users/me/development/apps/my_app/src.wasm doesn't exist
as directory
/Users/me/development/apps/my_app/src doesn't exist
webpack 5.51.1 compiled with 1 error in 47 ms
1
因此 console.log
命令未在 IEx 中打印。会不会有关系?可能是测试代码是 运行ning 的命令,IEx 中的 运行ning 是一个“不同的”webpack 命令吗?是不是找不到 webpack.config?
创建 dist/main.js 的原因是当 webpack 运行 时它无法找到 webpack.config.js 所以 dist/main.js 是默认行为.
我在将 filename
更新为函数时发现了这一点。然后我在其中调用 console.log("test")
并希望在 IEx 中看到它。控制台日志从未打印出来。
然后我 运行 常规 mix phx.server
我确实得到了新的输出。
在 dev.exs
中有:
watchers: [
node: [
"node_modules/webpack/bin/webpack.js",
"--mode",
"development",
"--progress",
"--watch",
"--watch-options-stdin",
cd: Path.expand("../assets", __DIR__)
]
]
这一切看起来都符合预期,但实现方式不同。 (它正在使用 cd: Path.expand
但我现在才注意到这一点。)
那么,为什么一个不工作而另一个很好呢?
细看时
defp compile_assets(_) do
Mix.shell().cmd("./assets/node_modules/webpack/bin/webpack.js --mode development",
quiet: false
)
end
我决定看看我是从哪里得到这个的(来自 Wallaby 文档)
我返回文档并注意到它已更改。
更改如下: https://github.com/elixir-wallaby/wallaby/commit/834bdb726228349f800837e470a0c77cd2f4a6bd
现在代码应该是:
defp compile_assets(_) do
Mix.shell().cmd("cd assets && ./node_modules/.bin/webpack --mode development",
quiet: true
)
我不知道为什么我们需要 cd 到资产而不是我们以前拥有的资产,但现在可以了。