你好开始在特定的角度项目中使用spring boot,我正在使用jhipster框架,我设置了我的webpack配置并且似乎工作,很好,现在我想要我的角度项目中的每个图像通过“app”文件夹的同一级别上的公共目录“assets”从“webpack:build”命令中检索,遵循项目的结构:
mvnw
mvnw.cmd
node_modules
package-lock.json
package.json
pom.xml
proxy.conf.json
src +
|- main + -- java
| -- resoruces
| -- webapp + -- 404.html
|-- app+
|-- assets+ //here are my images
|-- content+
|-- custom-typings.d.ts
|-- favicon.ico
|-- filename.txt
|-- i18n
|-- index.html
|-- robots.txt
|-- sw.js
|-- swagger-ui
target
tsconfig-aot.json
tsconfig.json
tsconfig.webpack.json
tslint.json
typedoc.json
typedoc.json.bak
webpack + --
|-- dist
|-- empty.js
|-- head-config.common.js
|-- helpers.js
|-- html-elements-plugin
|-- logo-jhipster.png
|-- modules
|-- resource-override.js
|-- utils.js
|-- webpack.common.js
|-- webpack.dev.js
|-- webpack.prod.js
|-- webpack.test.js
|-- webpack.config.js
yarn.lock
现在我的问题我在“app”角项目的不同目录中的不同文件中有很多图像,它们都有这个相对路径:
<img class="image" src="assets/img/pictures/5.jpg">
当我运行“webpack:build”时:
"webpack:build": "yarn run cleanup && yarn run webpack:build:main",
它告诉我我找不到图像,这是错误:
ERROR in ./src/main/webapp/app/tutorial/extra/search-results/search-results.template.html
Module not found: Error: Can't resolve './assets/img/pictures/5.jpg'
html希望我设置绝对路径,例如../../../assets/img/pictures/5.jpg,但是 这是很好的因为我还没有设置webpack配置,但是在我设置webpack配置之后错误仍然存在,这里是以下代码(注意我只放了webpack.common.js和webpack.dev.js因为问题就在这里,如果您现在需要其他文件,请您可以看到我设置了“copi-webpack-plugin”和图片的加载器:
webpack.common.js
const webpack = require('webpack');
const helpers = require('./helpers');
const AssetsPlugin = require('assets-webpack-plugin');
const IgnorePlugin = require('webpack/lib/IgnorePlugin');
const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const HtmlElementsPlugin = require('./html-elements-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineManifestWebpackPlugin = require('inline-manifest-webpack-plugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
const ngcWebpack = require('ngc-webpack');
const StringReplacePlugin = require('string-replace-webpack-plugin');
const MergeJsonWebpackPlugin = require("merge-jsons-webpack-plugin");
const utils = require('./utils.js');
/**
* Webpack Constants
*/
const HMR = helpers.hasProcessFlag('hot');
const AOT = process.env.BUILD_AOT || helpers.hasNpmFlag('aot');
const METADATA = {
title: 'DialogoPA',
baseUrl: '/',
isDevServer: helpers.isWebpackDevServer(),
HMR: HMR,
AOT: AOT
};
module.exports = function (options) {
const DATAS = {
VERSION: `'${utils.parseVersion()}'`,
DEBUG_INFO_ENABLED: options.env === 'development',
SERVER_API_URL: `""`
};
const path = require('path');
const isProd = options.env === 'production';
return {
performance: { hints: false },
entry: {
polyfills: './src/main/webapp/app/polyfills',
global: './src/main/webapp/content/scss/global.scss',
main: './src/main/webapp/app/app.main',
vendor: './src/main/webapp/app/vendor'
},
resolve: {
extensions: ['.ts', '.js', '.json'], // JHIPSTER
modules: [helpers.root('src/main/webapp'),'node_modules',helpers.root('node_modules')] // JHIPSTER
},
stats: {
children: false
},
module: {
rules: [
{ test: /bootstrap\/dist\/js\/umd\//, loader: 'imports-loader?jQuery=jquery' },
{
test: /\.html$/,
loader: 'html-loader',
options: {
minimize: true,
caseSensitive: true,
removeAttributeQuotes:false,
minifyJS:false,
minifyCSS:false
},
exclude: ['./src/main/webapp/index.html',helpers.root('src/main/webapp/index.html')]
},
{
test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
loaders: ['file-loader?hash=sha512&digest=hex&name=content/[hash].[ext]']
},
{
test: /\.(jpe?g|png|gif|svg|woff2?|ttf|eot)$/i,
loaders: ['file-loader?hash=sha512&digest=hex&name=assets/[hash].[ext]']
},
{
test: /manifest.webapp$/,
loader: 'file-loader?name=manifest.webapp!web-app-manifest-loader'
},
{
test: /app.constants.ts$/,
loader: StringReplacePlugin.replace({
replacements: [{
pattern: /\/\* @toreplace (\w*?) \*\//ig,
replacement: (match, p1, offset, string) => `_${p1} = ${DATAS[p1]};`
}]
})
},
{
test: /\.ts$/,
enforce: 'pre',
loaders: 'tslint-loader',
exclude: ['node_modules', new RegExp('reflect-metadata\\' + path.sep + 'Reflect\\.ts')]
},
{
test: /\.ts$/,
loaders: [
'ng-router-loader',
'angular2-template-loader',
'awesome-typescript-loader'
],
exclude: ['node_modules/generator-jhipster']
},
{
test: /\.scss$/,
loaders: ['to-string-loader', 'css-loader', 'sass-loader'],
exclude: /(vendor\.scss|global\.scss)/
},
{
test: /(vendor\.scss|global\.scss)/,
loaders: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader']
},
{
test: /\.css$/,
loaders: ['to-string-loader', 'css-loader'],
exclude: /(vendor\.css|global\.css)/
},
{
test: /(vendor\.css|global\.css)/,
loaders: ['style-loader', 'css-loader']
},
{
test: /\.json$/,
use: 'json-loader'
},
]
},
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(options.env)
}
}),
new CheckerPlugin(),
new webpack.optimize.CommonsChunkPlugin({
name: 'polyfills',
chunks: ['polyfills']
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
chunks: ['main'],
minChunks: module => utils.isExternalLib(module)
}),
new webpack.optimize.CommonsChunkPlugin({
name: ['polyfills', 'vendor'].reverse()
}),
new webpack.optimize.CommonsChunkPlugin({
name: ['manifest'],
minChunks: Infinity,
}),
new webpack.ContextReplacementPlugin(
/angular(\\|\/)core(\\|\/)@angular/,
utils.root('src/main/webapp/app'), {}
),
new CopyWebpackPlugin([
{ from: './src/main/webapp/assets',to: 'assets'},
{ from: './node_modules/swagger-ui/dist/css', to: 'swagger-ui/dist/css' },
{ from: './node_modules/swagger-ui/dist/lib', to: 'swagger-ui/dist/lib' },
{ from: './node_modules/swagger-ui/dist/swagger-ui.min.js', to: 'swagger-ui/dist/swagger-ui.min.js' },
{ from: './src/main/webapp/swagger-ui/', to: 'swagger-ui' },
{ from: './src/main/webapp/favicon.ico', to: 'favicon.ico' },
{ from: './src/main/webapp/manifest.webapp', to: 'manifest.webapp' },
{ from: './src/main/webapp/robots.txt', to: 'robots.txt' }
]),
new HtmlWebpackPlugin({
title: METADATA.title,
template: './src/main/webapp/index.html',
chunksSortMode: 'dependency',
metadata: METADATA,
inject: 'body'
}),
new ScriptExtHtmlWebpackPlugin({
sync: /polyfills|vendor/,
defaultAttribute: 'async',
preload: [/polyfills|vendor|main/],
prefetch: [/chunk/]
}),
new webpack.ProvidePlugin({
jQuery: 'jquery',
$: 'jquery',
jquery: 'jquery',
'window.jQuery': 'jquery',
Popper: 'popper.js/dist/umd/popper.js',
Tether: 'tether',
'window.Tether': 'tether',
Hammer: 'hammerjs/hammer',
Shuffle: 'shufflejs',
d3: 'd3',
Rickshaw: 'rickshaw',
nv: 'nvd3',
moment: 'moment',
fullCalendar: 'fullcalendar',
Raphael: 'webpack-raphael',
'window.Raphael': 'webpack-raphael',
Skycons: 'skycons/skycons',
Dropzone: 'dropzone',
Alert: "exports-loader?Alert!bootstrap/js/dist/alert",
Button: "exports-loader?Button!bootstrap/js/dist/button",
Carousel: "exports-loader?Carousel!bootstrap/js/dist/carousel",
Collapse: "exports-loader?Collapse!bootstrap/js/dist/collapse",
Dropdown: "exports-loader?Dropdown!bootstrap/js/dist/dropdown",
Modal: "exports-loader?Modal!bootstrap/js/dist/modal",
Popover: "exports-loader?Popover!bootstrap/js/dist/popover",
Scrollspy: "exports-loader?Scrollspy!bootstrap/js/dist/scrollspy",
Tab: "exports-loader?Tab!bootstrap/js/dist/tab",
Tooltip: "exports-loader?Tooltip!bootstrap/js/dist/tooltip",
Util: "exports-loader?Util!bootstrap/js/dist/util"
}),
new HtmlElementsPlugin({
headTags: require('./head-config.common')
}),
new MergeJsonWebpackPlugin({
output: {
groupBy: [
{ pattern: "./src/main/webapp/i18n/it/*.json", fileName: "./i18n/it.json" }
// jhipster-needle-i18n-language-webpack - JHipster will add/remove languages in this array
]
}
}),
new StringReplacePlugin({
name: 'webpackManifest',
}),
new LoaderOptionsPlugin({}),
new ngcWebpack.NgcWebpackPlugin({
disabled: !AOT,
tsConfig: helpers.root('tsconfig.webpack.json'),
}),
new InlineManifestWebpackPlugin()
],
node: {
global: 'window', // true
crypto: 'empty',
process: true,
module: true, // false
clearImmediate: false,
setImmediate: false
}
};
};
webpack.dev.js
/**
* Webpack Plugins
*/
const AddAssetHtmlPlugin = require('add-asset-html-webpack-plugin');
const DefinePlugin = require('webpack/lib/DefinePlugin');
const NamedModulesPlugin = require('webpack/lib/NamedModulesPlugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const HotModuleReplacementPlugin = require('webpack/lib/HotModuleReplacementPlugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// JHIPSTER
const webpack = require('webpack');
const writeFilePlugin = require('write-file-webpack-plugin');
const webpackMerge = require('webpack-merge');
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');
const WebpackNotifierPlugin = require('webpack-notifier');
const path = require('path');
const utils = require('./utils.js');
const helpers = require('./helpers');
const commonConfig = require('./webpack.common.js');
/**
* Webpack Constants
*/
const ENV = process.env.ENV = process.env.NODE_ENV = 'development';
const HOST = process.env.HOST || 'localhost';
const PORT = process.env.PORT || 3000;
const PUBLIC = process.env.PUBLIC_DEV || HOST + ':' + PORT;
const AOT = process.env.BUILD_AOT || helpers.hasNpmFlag('aot');
const HMR = helpers.hasProcessFlag('hot');
const METADATA = {
host: HOST,
port: PORT,
public: PUBLIC,
ENV: ENV,
HMR: HMR,
AOT: AOT
};
module.exports = function (options) {
const isProd = process.env.NODE_ENV === 'production';
return webpackMerge(commonConfig({env: ENV}), {
devtool: 'eval-source-map',
devServer: {
contentBase: './target/www',
proxy: [{
context: [
'/api',
'/management',
'/swagger-resources',
'/v2/api-docs',
'/h2-console',
'/auth'
],
target: 'http://127.0.0.1:8080',
secure: false
}],
watchOptions: {
ignored: /node_modules/
},
port: METADATA.port,
host: METADATA.host,
hot: METADATA.HMR,
public: METADATA.public,
historyApiFallback: true,
setup: function(app) {},
},
output: {
path: utils.root('target/www'),
filename: 'app/[name].bundle.js',
chunkFilename: 'app/[id].chunk.js',
//They are needed ???????
// library: 'ac_[name]',
// libraryTarget: 'var'
},
module: {
// they are all defined on the common for my use case
},
plugins: [
new BrowserSyncPlugin({
host: 'localhost',
port: 9000,
proxy: {
target: 'http://localhost:9060'
}
}, {
reload: false
}),
new webpack.NoEmitOnErrorsPlugin(),
new webpack.NamedModulesPlugin(),
new writeFilePlugin(),
new webpack.WatchIgnorePlugin([
utils.root('src/test'),
]),
new WebpackNotifierPlugin({
title: 'JHipster',
contentImage: path.join(__dirname, 'logo-jhipster.png')
}),
new DefinePlugin({
'ENV': JSON.stringify(METADATA.ENV),
'HMR': METADATA.HMR,
'process.env.ENV': JSON.stringify(METADATA.ENV),
'process.env.NODE_ENV': JSON.stringify(METADATA.ENV),
'process.env.HMR': METADATA.HMR,
'process.env.BROWSER': JSON.stringify(true),
}),
],
node: {
global: true,
crypto: 'empty',
process: true,
module: false,
clearImmediate: false,
setImmediate: false
}
});
};
我肯定知道,因为我在其他项目中看到我可以通过设置路径“assets / to / path / images”来查找图像而不添加“../”前缀,但我找不到解决方案对我的问题,任何人都可以给我一些建议吗?
事先提前。