I've read a bunch of stuff on this, but I still can't seem to serve my files the way I want.
my file structure:
root/
/dist/ <= here is where webpack is putting bundles
/public/ <= here are where all my images are stored
/src/ <= here are my source files
template.html <= some files under src
index.js
webpack.config.js <= files under root
index.html <= html now at root by webpack
My webpack.config has htmlWebpackPlugin configured like so:
new HtmlWebpackPlugin({
"template": "./src/template.html",
"filename": "../index.html", <= moved up to root?
"hash": false,
"inject": true,
"compile": true,
"favicon": false,
"minify": false,
"cache": true,
"showErrors": true,
"chunks": "all",
"excludeChunks": [],
"title": "Webpack App",
"xhtml": true,
"chunksSortMode": 'none' //fixes bug
}),
and my output configured like this:
output: {
filename: '[name].[chunkhash:4].js',
chunkFilename: '[name].[chunkhash:4].js', //name of non-entry chunk files
path: path.resolve(__dirname, 'dist'),
publicPath: "/public" <= not really sure about this
},
So the publicPath, as I understand it, is where the "src" property on image elements will be served from throughout the code, correct? So, in my code, I can just put src='/images....' because '/public' will be prepended. Right?
Also, I read something about 'webpack-dev-server' will serve files from that folder (public) too. Does dev server ever look in the webpack-created dist directiory? Or is that completely separate?
So, as you can see, I moved the index.html up to the root. Not sure if I needed to do that, but I'm trying to figure out how to serve my images that I'm calling from within the html itself.
How can I serve my files easily from within the code '/images/....' and also serve them from the html directly? Should I serve the html from the 'public' folder or will that affect the serving of the dist bundles?
With devServer it might be easiest to just mount your assets-directory., webpack-dev-server uses express behind the scenes so:
const express = require('express');
module.exports = {
...
devServer:{
host: '0.0.0.0',
port: 8080,
before(app) {
app.use('/assets/uploads', express.static(path.resolve('C:\\temp')));
}
}
}
I mean, you'll probably do something similar on your production server anyway.
ie. location /assets/uploads { root /var/www/project; }; in nginx or whatever.
Another method is to use CopyWebPackPlugin:
new CopyWebpackPlugin(
[
{
from: path.resolve(__dirname, 'public'),
to: path.resolve(__dirname, 'dist'),
ignore: [ 'index.html', ... ]
}
]
),
Yet another method could be to add your images to code require('image1.jpg'); somewhere in your entry and add a file-loader and let webpack handle the rest. Webpack is so flexible. If you wonder about the folder-structure, disable webpack-dev-server temporarily so you can see the actual output.
Sorry, I just realized I answered your title question and ignored everything else.
So the publicPath, as I understand it, is where the "src" property on
image elements will be served from throughout the code, correct? So,
in my code, I can just put src='/images....' because '/public' will be
prepended. Right?
No, publicPath is where the static files (production build) on your server are served from, and webpack is going to require all other chunks using that prefix.
Also, I read something about 'webpack-dev-server' will serve files
from that folder (public) too. Does dev server ever look in the
webpack-created dist directiory? Or is that completely separate?
webpack-dev-server servers files from memory, all files compiled.
So, as you can see, I moved the index.html up to the root. Not sure if
I needed to do that, but I'm trying to figure out how to serve my
images that I'm calling from within the html itself.
Not needed.
How can I serve my files easily from within the code '/images/....'
and also serve them from the html directly? Should I serve the html
from the 'public' folder or will that affect the serving of the dist
bundles?
You import your images like: import MyImage from './cat-image.png.
And puts on the src attr in the img tag.
<img src={MyImage} />
Webpack will see the import (you have to have file-loader installed and configured on webpack config file) and will parse it. All those parsed images are going to be outputted to the destination folder (dist or whatever you had configured on your output).
Related
I'm making an app using plain HTML and TypeScript (compiled into JS ofc). I'm not using anything external and I'm also not using TS modules - I had issues with calling methods from global scope.
I have the following folder structure:
- build
- page
- index.html
- src
- include
- <bunch of .ts files>
- tsconfig.json
- <few .ts files>
- tsconfig.json
This is the \src\tsconfig.json file:
{
"compilerOptions": {
"outDir": "../build/",
"target": "ES6",
"lib": ["DOM", "esnext"],
"downlevelIteration": true
},
"compileOnSave": true
}
This is the \src\include\tsconfig.json file:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outFile": "../../build/Include.js",
}
}
What I want
I want to compile the contents of \src\include\ into a single file to \build\include.js because manually linking many script files in \build\page\index.html would be dumb.
The rest of the .ts files in \src can be compiled into individual files to \build\.
The way it's set up right now works, but the compilation of the \src\ folder (I'm compiling each folder separately) also compiles the \src\include\ folder into \build\include\<individual compiled files>.js
What I've tried
If I exclude the \src\include\ from \src\tsconfig.json, I can't compile it because the classes from the include folder cannot be found in the .ts files in \src\
Other SO question answers I've tried:
https://stackoverflow.com/a/69568072/19674384 - Classes from the include folder cannot be found despite being explicitly included (wtf?)
https://stackoverflow.com/a/40781823/19674384 - Classes from the include folder still cannot be found
https://stackoverflow.com/a/65282934/19674384 - noEmit doesn't compile anything, the second suggestion seems like something else entirely
Am I doing something wrong or should I approach this completly differently?
So consider the following script command to run via npm run: webpack -p --optimize-minimize
Is there any way to say: Keep comments?
webpack version 2 is used.
In most applications you would not want to keep comments, but in this particular case I want to keep them, while still minifying the "script" Is this possible?
Webpack's webpack.optimize.UglifyJsPlugin has a couple of options which might fit your needs.
comments options accepts a regex or function to tell UglifyJs which comment to preserve.
extractComments let you even extract the comments to separate txt files.
Set it up like this:
plugins: [
new webpack.optimize.UglifyJsPlugin({
comments: true, // or function/regex
// Further UglifyJs config
})
],
I'm currently tasked with building 2 UI's for a service I've constructed.
The output from both of these UI's will need to end up in the same root folder.
I found the section that names the basic bundles in the "aurelia.json" file, and renamed the bundles created for my project, when built, my project as expected created 2 new bundles in the scripts directory with the new names.
However, upon running my project, I then found that index.html was getting a 404 trying to load the "vendor-bundle" (Which I had renamed to 'service-vendor-bundle').
No problem there, I just edited index.html to reference the new file, and bingo, 404 resolved.
The problem is however, that "service-vendor-bundle" can now not load "service-app-bundle".
I assumed (Probably incorrectly) that, when I renamed the bundles in my aurelia.json file, that the build output would also be configured appropriately to load the files in.
I need to be able to customize this beacuse once the 2 aurelia apps are finished, they will need to share a scripts folder, so I'll need
uione.html to load "scripts\uione-vendor-bundle.js" and "scripts\uione-app-bundle.js"
and I'll need
uitwo.html to load "scripts\uitwo-vendor-bundle.js" and "scripts\uitwo-app-bundle.js"
The final file layout once on the server will look something like the following:
root
uione.html
uitwo.html
scripts
uione-vendor-bundle.js
uione-app-bundle.js
uitwo-vendor-bundle.js
uitwo-app-bundle.js
images
*.png
Both client apps have to be developed separate from each other and be stand alone, so I can't combine them into one app, and I cant put them into seperate folders as the service that will be serving them is a custom in house built service, specifically configured to only serve from a single folder, with a single scripts and images folder.
My aurelia.json file currently looks like this:
.........
"plugins": [
{
"name": "text",
"extensions": [
".html",
".css"
],
"stub": true
}
]
},
"options": {
"minify": "stage & prod",
"sourcemaps": "dev & stage"
},
"bundles": [
{
"name": "uione-app-bundle.js",
"source": [
"[**/*.js]",
"**/*.{css,html}"
]
},
{
"name": "uione-vendor-bundle.js",
"prepend": [
"node_modules/bluebird/js/browser/bluebird.core.js",
"node_modules/requirejs/require.js"
],
..........
and I'm using the Aurelia cli tool (au ...) for my Aurelia based tasks.
Any pointers on how to achieve this would be great.
I think you're on the right track by customizing the bundle names.
What you can do is manually load both the vendor bundle and the app bundle. That way the app modules are already downloaded and ready to use, instead of letting the vendor bundle try to download it manually.
index.html
<body aurelia-app="main">
<script src="scripts/my-special-vendor-bundle.js" data-main="aurelia-bootstrapper"></script>
<script src="scripts/my-special-app-bundle.js"></script>
</body>
I have tested this and it is working fine for me. I am using this manual loading technique in my own project to allow ASP.Net script versioning to provide cache-busting (see my answer here).
I have just started using Webpack via a recommendation and am looking for some guidance on how it should be implemented for build and deploy purposes.
I currently have it up and running nicely using webpack-dev-server and some Gulp tasks.
Traditionally I would use Gulp or Grunt to concat files among other things and then use the task runner to copy all my files and assets to a dist or build directory from where I would deploy everything.
At the minute, Webpack does it's thing and builds the bundle file, images etc and then copies them to the build dir, using the [hash].js naming convention.
So my question is, what is the standard practice for then copying over my index.html file and then correctly linking it to the js file to be used in production.
Unless I am completely misunderstanding how Webpack should be used, should there not be some way for me to do this, with the ultimate outcome being me having the ability to navigate to the build dir and see my app up and running as it should be?
I am currently using a plugin to move my index.html. Make sure your webpack.output.publicPath points to your site so it can link images and other resources.
var CopyWebpackPlugin = require('copy-webpack-plugin');
var webpack_config = {
//Other configs here
output: {
publicPath: 'http://localhost/'
},
//Other configs here
plugins:[
new CopyWebpackPlugin([
{from: './index.html', to: './index.html'},
], {
ignore: [
'*.txt',
{glob: '**/*', dot: true}
]
})
],
//Other configs here
}
I've got a project where src/main/webapp/com/mycompany/frontend/page/index.js depends on target/webjars/log4javascript/1.4.10/log4javascript.js.
I've added package.json alongside index.js with the following contents:
{
"browser":
{
"log4javascript": "../../../../../../../target/webjars/log4javascript/1.4.10/log4javascript.js"
}
}
I've got many other dependencies in the target directory. Is there a way for me to avoid repeating ../../../../../../../target/ for every dependency?
One option is to put the directory that contains your local modules, or a symlink to it, in node_modules, such as node_modules/app and then reference your requires as app/..., e.g. I believe this would work
{
"browser":
{
"log4javascript": "app/target/webjars/log4javascript/1.4.10/log4javascript.js"
}
}
Or you could structure it however you want, e.g. node_modules/log4javascript (which, if you have symlinks, could point to /whatever/target/webjars/log4javascript).
This makes it so that require() will find it in the same fashion as npm modules, without publishing it to npm. The main drawback to this is that it breaks the ability to programatically configure transforms, e.g. with browserify('app/entry').transform(whatever), app/entry and other files in the dependency graph that are under node_modules will not have the transform applied to them.
Check out the section Using Non-Relative Paths in this article.
You can use grunt-browserify's aliasMapping option to specify the root of your app:
aliasMappings: [{
cwd: 'src',
dest: 'myApp',
src: ['**/*.js']
}]
and then you can directly refer to everything from the root path, without having to ever use any dreaded ../'s:
require("myApp/target/webjars/log4javascript/1.4.10/log4javascript.js")
Of course, this doesn't resolve the problem that it's still a very long path.
The article's next paragraph makes a very good point: if you're calling things way over at the other end of your application like that, it's a good sign that things may not be correctly architected.
Can you split the functionality into smaller modules? Perhaps make log4javascript its own module?
Add to my answer, from discussion below:
If log4javascript is in your package.json file as a browser (non-NPM) module, you should just be able to require it with require('log4javascript')