How to get a filename renamed by Webpack? - javascript

I'm using a webassembly file compiled by Emscripten in my project.
And since my project uses Webpack, it renames all files, then the Emscripten module can't find more the webassembly file.
Then I need to get the new filename of the webassembly file to can load it.
I found this workaround, but I want a better solution, because I don't want do change the webpack.config.js with configurations about the .wasm files.
Explain the context: I have a project called bursh that it uses Webpack and imports a module called scissors which it has the webassembly files. So I'm looking for a solution which doesn't need to update the configurations, because of the isolation of responsibilities - doesn't make sense to set configurations at brush for some reason by scissors

From your description you might want to look into copy-webpack-plugin. Webpack normally bundles multiple files into one or several larger files, but if you additionally want to copy files into your build, this plugin can do just that.

I resolved the problem. My solution is adding Webpack at scissors in order to set the configurations in this project.
const path = require('path')
const rules = [
{
loader: 'file-loader',
test: /huffman\.wasm$/,
type: 'javascript/auto',
},
]
rules.concat()
module.exports = {
devtool: 'source-map',
entry: './src/index.js',
module: {
rules,
},
node: {
fs: 'empty',
},
output: {
filename: 'scissors.js',
libraryTarget: 'commonjs2',
path: path.join(__dirname, './dist'),
sourceMapFilename: 'scissors.js.map',
},
}
I don't know if this is the best solution, because now I have a Webpack in brush project and also in scissors project, then it will increase complexity in my code... But in this way I can keep the isolation of responsibilities.

Related

Webpack bundling a library that uses another library that contains WebAssembly gives several files as output, but the paths to them are not relative

I'm making a custom element using Svelte, that I plan to publish to NPM as a library. The component uses a library I made, that uses WebAssembly. When I build the Svelte library with Webpack, it gives me three files.
1.1.js
[hash].wasm
bundle.js
bundle.js references both the wasm file and 1.1.js. This works in the project folder itself, but when I npm pack it and try to use it in another project, it can't find the 1.1.js file or the wasm file. Apparently, the paths are relative to the website root instead of eg. /1.1.js instead of node_modules/packageName/1.1.js. I really have no clue how to fix this. Any ideas?
The start of my webpack config file looks like this:
const config: webpack.Configuration & WebpackDevServer.Configuration = {
entry: {
bundle: [
'./src/main.ts',
],
},
resolve: {
alias: {
// Note: Additional aliases will be loaded automatically from `tsconfig.compilerOptions.paths`
svelte: path.resolve('node_modules', 'svelte'),
},
extensions: ['.mjs', '.js', '.ts', '.svelte'],
mainFields: ['svelte', 'browser', 'module', 'main'],
},
output: {
path: __dirname + '/public/build',
filename: '[name].js',
chunkFilename: '[name].[id].js',
},
...
I have tried both importing the bundle.js directly with HTML, and importing the package using import x from y syntax in a JavaScript file, and running Webpack on the project that uses the Svelte component. I get errors such as this ChunkLoadError: Loading chunk 1 failed. (error: http://localhost:8080/1.1.js)

Webpack - Bundle multiple/different versions of .css files

I would like to make my bundled .css file being generated by Webpack more configurable, so I can output different 'versions' - based on the same .css file - to make the life of developers working on my project in the future easier.
I would like to have the following steps:
Concat of all SCSS into CSS (bundle.css)
Minimize output of step 1 (bundle.min.css)
Embed all images from step 2 (bundle.b64.min.css)
Embed all fonts from step 3 (bundle.bs64.fonts.min.css)
In the end - after my build process -, I would have 4 distinct files in my dist folder. Would that me possible?
The way I'm currently doing it, I run a different script for each step - deletes dist folder, goes through project, produces the output. I would like to have a single script that does all of it at once without having to go through my project 4 times.
I kind of found a solution for it here:
Webpack Extract-Text-Plugin Output Multiple CSS Files (Both Minified and Not Minified)
But, for my specific case, I would have to return 4 different configurations in a array instead of a single object.
Ok so based on our comment conversation i'm gonna give you a workflow of steps 1-4, but with regular assets handling, not a bundling of assets (which i haven't heard of but maybe someone else can elaborate there).
So the steps:
bundle all scss files into 1 bundle.css
make sure this bundle is minified
add assets management to build for images
add assets management to build for fonts
The important things:
This workflow is basically a built by configuration. configuring the npm scripts with the package.json file, and configuring webpack with config.webpack.js. This will allow you to simply run 1 command to build your project: npm run build. note: For simplicity's sake i am going to ignore production/development/etc environments and focus on a single environment.
package.json:
This is used to set up the command that will actually run when you input npm run build in the terminal (from the project dir of course).
since we are avoiding different environments for now and as you are not using Typescript this is a very simple configuraton:
"scripts": {
"build": "webpack",
},
that's all you have to add. It sound's stupid now but when the project will get more complex you are going to like those scripts so better start off making them already.
webpack.config.js:
The major lifting will be made in this configuration file. This basically tells webpack what to do when you run it (which is what npm run build is doing).
first off let's install some plugins:
npm install --save-dev file-loader
npm install --save-dev html-webpack-plugin
npm install --save-dev mini-css-extract-plugin
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
mode: 'production',
devtool: 'source-map'
entry: './client/src/app.jsx',
output: {
path: path.join(__dirname, 'client/dist/public'),
filename: 'bundle.[hash].js'
},
module: {
rules: [
{
test: /\.s?css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
options: {
hmr: false
}
},
'css-loader',
'sass-loader'
]
},
{
test: /\.(png|svg|jpg|gif)$/,
use: ['file-loader']
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
'file-loader'
]
}
]
},
resolve: {
extensions: ['.js', '.json', '.jsx']
},
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './client/src/index_template.html'
}),
new MiniCssExtractPlugin({
filename: 'style.[hash].css',
chunkFilename: '[id].[hash].css'
}),
]
};
Notice i've added the htmlWebpackPlugin because it makes it easier to reference the correct hashed bundles automatically. Also I've assumed the app is a react app but you can just change the entry point to where your app loads from.
This is quite hard to do of the fly without testing things out, but i hope this gives you enough reference as to what you should change and do to get going with it.
Again i strognly recommend the webpack.js guides and documentation, they are very thorough and once you start getting the hang of it things start working smoothly.

Webpack tree shaking not working between packages

Good evening!
I have been trying for a few days to get tree shaking between different packages to work.
Before going further, I have created a minimum repro that I will explain throughout this post: https://github.com/Apidcloud/tree-shaking-webpack
I have also opened an issue on webpack repo: https://github.com/webpack/webpack/issues/8951
For simplicity sake, the example just uses webpack. Babel is not used.
The above example has two packages, both with their respective bundle:
core - exports 2 functions, cube and unusedFn
consumer - imports cube from core and exports its own function, consumerFn
Core package
Note that square function is not exported in the index.js file. It's a way to know that tree shaking is indeed working within core at least, as it's not included in the final bundle (which is correct).
Consumer package
As you can see, only cube is being imported from core. It then exports its own function (consumerFn) consuming cube.
Problem
The problem is that the consumer bundle is including everything from the core bundle. That is, it's including unusedFn when it shouldn't, resulting in a bigger bundle.
Ultimately, the goal is to do the same in a monorepo with multiple packages. There's no point on having them if each package is bundling the everything from the others. The goal is to bundle only what's necessary for each package.
Using optimizationBailout I can see that ModuleConcatenation plugin is issuing some warning messages. I also used --verbose flag:
Here's my webpack.config.js:
const path = require('path');
module.exports = {
mode: 'production',
entry: {
core: './src/index.js',
consumer: './consumer/index.js'
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, 'dist'),
// for simplicity sake I removed the UMD specifics here.
// the problem is the same, with or without it.
},
optimization: {
usedExports: true,
sideEffects: true
},
stats: {
// Examine all modules
maxModules: Infinity,
// Display bailout reasons
optimizationBailout: true
}
};
I also have "sideEffects": false in the package.json.
I went through webpack's guide too, but I'm not sure what is missing.
Related issues:
webpack-3-babel-and-tree-shaking-not-working
webpack-including-unused-exports-in-final-bundle-not-tree-shaking

Webpack 2: How do I generate a bundle.js from Bootstrap premade template?

I want to generate a bundle.js from this pre-esxisting bootstrap template (it uses less) https://github.com/BlackrockDigital/startbootstrap-sb-admin-2
I tried to generate it but I failed since the styles are never generated and the bundle.js is empty as you can see in the "dist" folder(This was expected since the index.js which is the entry point is empty as well. https://github.com/juanlet/webpack . What should I do in order for webpack2 to include all the js,css and less files that came with the template and put it in a bundle.js?. Should I include every file on the index.js entry file?. I'm running out of ideas. Any article, documentation or instruction will be very welcomed. Thank you very much.
If you want to build this out with webpack, your first step is actually using whatever your entry point is to import or require other libs/files.
So, for example, if your entry point in your wepback.config.js is
entry: {
bundle: './src/js/api/index.js',
vendor: VENDOR_LIBS
},
Then that file needs to contain imports that you wish to include in that file. And then those files include other files and so on, until you have all your files bundled up through the root of your tree (index). In a very simple way, this is what webapack does: it imports/requires your files, bundles them, and loads them depending on your configuration.
In order to load/compile your LESS, you will either have to include it as an import in your JS files, or you could also use extract-text-webpack-plugin to generate a separate CSS bundle.
This is the best overview I can give to this question since I don't know the exact way your want to take your code and bundle it. Feel free to ask questions if you have them, and I will edit my answer to try and help answer them.
EDIT: This is an example of an older config I have extracting SASS into it's own file. It's using v1, but it more or less works the same for webpack 2. I just don't have an example with me right now: (Here is the documentation for using extract in v2. A little different, but not too much).
module.exports = {
devtool: 'eval',
entry: [
'webpack-dev-server/client?http://localhost:3000',
'webpack/hot/only-dev-server',
'babel-polyfill',
'./app/index',
],
resolve: {
extensions: ['', '.js']
},
output: {
path: path.join(__dirname, 'public'),
filename: 'bundle.js',
publicPath: '/public/'
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
new ExtractTextPlugin('public/app.css'),
new DashboardPlugin(dashboard.setData)
],
module: {
loaders: [{
test: /\.js$/,
loaders: ['react-hot', 'babel'],
include: path.join(__dirname, '..', 'app')
},
// JSON
{
test: /\.json$/,
loaders: ['json-loader']
},
// Img
{
test : /\.(png|jpg|svg|eot|ttf|woff|raw)$/,
loader: 'url-loader?limit=4096'
},
// Sass
{
test: /\.scss$/,
loaders: [ 'style', 'css?sourceMap', 'postcss', 'sass?sourceMap' ]
}]
},
postcss: [autoprefixer({ browsers: ['last 2 versions'] })],
}
MAJOR EDIT:
An example repo exists here: https://github.com/thesublimeobject/webpack2example
Running webpack will bundle up your files, imported from an index.js file I created. This bundles all the external libraries which I installed via npm and removed them from the index.html file. I did not test any of the code that was generated since that's way beyond an answer to this question. Your LESS will also be bundled into the dist folder as a separate file you will need to provide a link to in the HTML (that's one thing I forgot to do is add links to the /dist, but I'm sure you can do that.

Webpack-dev-server doesn't build files on change

So I have the following webpack configuration :
import path from 'path';
module.exports = {
entry: {
index: './dev/index.js'
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: './dist/',
filename: 'bundle.js',
chunkFilename: '[id].bundle.js'
},
module:{
loader:{
test: /\.js$/,
exclude:path.resolve(__dirname, "node_modules"),
loader: 'js'
}
}
};
The problem is that when I do webpack --watchthe file does build in the /dist/ folder at every change. Yet when I run the webpack-dev-server the files don't even build. Why is that?
Please help.
The reason you are not seeing files emitted into your dist folder is because webpack-dev-server uses an in-memory filesystem
This allows for extremely fast incremental builds when your code changes. This was an intentional design on our part. You can view the resulting code in your browser and never need to reference those files.
It is not recommended by us, for the sake of build performance, but you can look in to plugins like write-file-webpack-plugin if you need this feature.
'webpack' writes your bundle to disk, whereas 'webpack-dev-server' loads the bundle into memory. So when running the latter command you wont see a new 'bundle.js' file appear in your file system, even though you should see output to the console reporting the bundling and the start up of the dev server).
The output.publicPath config key determines the location of the in-memory bundle on the host dev server. So if you set the publicPath to 'dist' then the index.html served by the webpack dev server will need a script tag in order to reference the bundle.

Categories