Apply loader to specific file - javascript

I'm following http://alexomara.com/blog/webpack-and-jquery-include-only-the-parts-you-need to bundle parts of jQuery using webpack.
// webpack.config.js
module.exports = {
entry: './entry',
output: {
filename: 'bundle.js'
},
module: {
loaders: [
{
test: /jquery\/src\/selector\.js$/,
loader: 'amd-define-factory-patcher-loader'
}
]
}
};
It turns out that node_modules/jquery/src/selector.js needs it own loader due to an AMD issue. But the loader is not being applied. I'm running under windows and maybe the regexp needs to be adjusted? I tried different expressions but no luck.
Any suggestions on how to debug? New to webpack.
As suggested, I added:
profile: true,
stats: {
reasons: true,
chunkModules: true,
chunkOrigins: true,
modules: true,
cached: true,
cachedAssets: true,
source: true,
errorDetails: true,
publicPath: true,
excludeModules: [
/e\.js/
]
Running webpack --display-modules yields
Hash: 4a092c0d4d9e158a9bd7
Version: webpack 1.10.1
Time: 970ms
Asset Size Chunks Chunk Names
bundle.js 876 kB 0 [emitted] main
[0] ./entry.js 529 bytes {0} [built]
factory:13ms building:12ms = 25ms
...
[14] ./~/jquery/src/traversing/var/rneedsContext.js 110 bytes {0} [built]
[0] 25ms -> [11] 161ms -> [13] 473ms -> factory:196ms building:3ms dependencies:1ms = 859ms
[15] ./~/jquery/src/selector.js 33 bytes {0} [built]
[0] 25ms -> [16] 172ms -> factory:449ms building:180ms = 826ms
[16] ./~/jquery/src/manipulation.js 15 kB {0} [built]
[0] 25ms -> factory:16ms building:156ms dependencies:443ms = 640ms
...
No errors. Nothing of any real value.

Apparently Webpack does not normalize the path separators, so we must alter the regex to accommodate Windows-style directory separators.
Here is a platform-independent regex you can use, so it can work on both *nix systems and Windows.
{ test: /jquery[\\\/]src[\\\/]selector\.js$/, loader: 'amd-define-factory-patcher-loader' }
I've also updated the blog post to use this form. If you continue to have trouble, let me know!
Full disclosure: I wrote the blog post to which this question is referring, and happened to discover this question about it today.

Not sure if you ever found the solution to this yourself however based on the comments section for the origional article:
http://alexomara.com/blog/webpack-and-jquery-include-only-the-parts-you-need/
It appears the correct regex when running on Windows is:
test: /jquery\\src\\selector\.js$/, loader: "amd-define-factory-patcher-loader"
Hope that helps!

Related

Why won't webpack ignore my node_modules?

I have tried configuring it multiple ways and reduced the config file to a bare minimal but it always compiles my node_modules folder.
I have tried using a regular expression as seen below, as well as inserting the direct path.
Webpack requires direct paths which I am using instead of the path module for clarity.
Webpack config file
// style-loader and css-loader are both required to handle .css files
const css = {
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
};
// babel-loader handles .js and .jsx files
const jsx = {
test: /\.jsx?/,
exclude: [
/node_modules/
],
use: {
loader: 'babel-loader',
options: {
presets: ['#babel/preset-env', '#babel/preset-react']
}
}
};
// this webpack configuration file supports these two file types
const file_types = {
rules: [
css,
jsx
]
};
const input = '/Users/c/top/frame/index.jsx';
const output = {
filename: 'bundle.js',
path: '/Users/c/top/frame-server/dist'
};
const stats = { warnings: true };
// combine above objects and export
const config_obj = {
stats: stats,
entry: input,
output: output,
module: file_types
};
module.exports = (env) => {
return config_obj;
};
Yet still I see them compiled:
asset bundle.js 209 KiB [compared for emit] [minimized] (name: main) 1 related asset
orphan modules 787 KiB [orphan] 460 modules
runtime modules 663 bytes 3 modules
cacheable modules 375 KiB
modules by path ./node_modules/ 155 KiB 22 modules
modules by path ./A1People/ 4.31 KiB 6 modules
modules by path ./F1PageUser/ 4.9 KiB 5 modules
modules by path ./F1Apex/ 2.87 KiB 4 modules
modules by path ./A1Article/ 3.43 KiB 4 modules
modules by path ./F1M1/ 2.9 KiB 4 modules
modules by path ./C0Images/ 2.02 KiB 3 modules
modules by path ./C2Menu/ 2.04 KiB 3 modules
modules by path ./C3BarAdmin/ 1.56 KiB
./node_modules/css-loader/dist/cjs.js!./C3BarAdmin/C3BarAdmin.css 504 bytes [built] [code generated]
+ 2 modules
+ 8 modules
webpack 5.69.1 compiled with 2 warnings in 6635 ms
I am following the documentation by webpack found here.
and version as follows:
"webpack": "^5.69.1",
"webpack-cli": "^4.9.2"
I am getting a strange warning but I don't know if it is relevant:
WARNING in ./node_modules/React/cjs/react.production.min.js
There are multiple modules with names that only differ in casing.
This can lead to unexpected behavior when compiling on a filesystem with other case-semantic.
Use equal casing. Compare these module identifiers:
* /Users/c/top/frame/node_modules/React/cjs/react.production.min.js
Used by 1 module(s), i. e.
/Users/c/top/frame/node_modules/React/index.js
* /Users/c/top/frame/node_modules/react/cjs/react.production.min.js
Used by 1 module(s), i. e.
/Users/c/top/frame/node_modules/react/index.js
# ./node_modules/React/index.js 4:2-59
# ./F1PageUser/ULogin.jsx 2:0-26 5:22-41 7:18-37 9:18-37 11:31-50
# ./F1PageUser/User.jsx 4:0-34 14:47-53
# ./F1Page/F1Page.jsx 8:0-44 21:57-63
# ./F1/F1.jsx 5:0-42 18:184-190
# ./index.jsx 8:0-29 12:36-38

bin/webpack error while introducing VueJS to Rails app

I'm trying to introduce Vue.JS by webpack. Now I'm struggling with an error while I execute bin/webpack.
The issue is similar to this one (Can't use vue component in my Rails5 app) but seems slightly different, as nothing will be changed if I remove tag in "/app/javascript/app.vue".
The gem file is below:
gem 'webpacker', github: 'rails/webpacker'
And the below is "/config/webpack/webpacker.yml":
# Note: You must restart bin/webpack-dev-server for changes to take effect
default: &default
source_path: app/javascript
source_entry_path: packs
public_output_path: packs
cache_path: tmp/cache/webpacker
# Additional paths webpack should lookup modules
# ['app/assets', 'engine/foo/app/assets']
resolved_paths: []
# Reload manifest.json on all requests so we reload latest compiled packs
cache_manifest: false
extensions:
- .vue
- .js
- .sass
- .scss
- .css
- .module.sass
- .module.scss
- .module.css
- .png
- .svg
- .gif
- .jpeg
- .jpg
development:
<<: *default
compile: true
# Reference: https://webpack.js.org/configuration/dev-server/
dev_server:
https: false
host: localhost
port: 3035
public: localhost:3035
hmr: false
# Inline should be set to true if using HMR
inline: true
overlay: true
compress: true
disable_host_check: true
use_local_ip: false
quiet: false
headers:
'Access-Control-Allow-Origin': '*'
watch_options:
ignored: /node_modules/
test:
<<: *default
compile: true
# Compile test packs to a separate directory
public_output_path: packs-test
production:
<<: *default
# Production depends on precompilation of packs prior to booting for performance.
compile: false
# Cache manifest.json for performance
cache_manifest: true
Error:
$ bin/webpack
(node:24139) ExperimentalWarning: The fs.promises API is experimental
Hash: 609c54cf56c50ef7c14a
Version: webpack 3.12.0
Time: 1760ms
Asset Size Chunks Chunk Names
hello-3fc5abe86ea1eca80c8f.js 248 kB 0 [emitted] hello
application-12a437e15157c0d4029c.js 3.27 kB 1 [emitted] application
hello-9cb5a7334a6577c3422968b9b9970b2f.css 134 bytes 0 [emitted] hello
hello-3fc5abe86ea1eca80c8f.js.map 293 kB 0 [emitted] hello
hello-9cb5a7334a6577c3422968b9b9970b2f.css.map 557 bytes 0 [emitted] hello
application-12a437e15157c0d4029c.js.map 3.19 kB 1 [emitted] application
manifest.json 402 bytes [emitted]
[0] (webpack)/buildin/global.js 509 bytes {0} [built]
[1] ./app/javascript/app.vue?vue&type=script&lang=js 362 bytes {0} [built]
[2] ./node_modules/babel-loader/lib??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./app/javascript/app.vue?vue&type=scrip
t&lang=js 1.66 kB {0} [built] [failed] [1 error]
[3] ./node_modules/extract-text-webpack-plugin/dist/loader.js??ref--1-0!./node_modules/style-loader??ref--4-1!./node_modules/css-loader
??ref--1-2!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib??ref--1-3!./node_modules/vue-loader/
lib??vue-loader-options!./app/javascript/app.vue?vue&type=style&index=0&id=6fb8108a&scoped=true&lang=css 41 bytes {0} [built]
[4] ./app/javascript/packs/application.js 515 bytes {1} [built]
[5] ./app/javascript/packs/hello.js 1.93 kB {0} [built]
[10] ./app/javascript/app.vue 978 bytes {0} [built]
[11] ./app/javascript/app.vue?vue&type=template&id=6fb8108a&scoped=true 212 bytes {0} [built]
[12] ./node_modules/vue-loader/lib/loaders/templateLoader.js??vue-loader-options!./node_modules/vue-loader/lib??vue-loader-options!./app
/javascript/app.vue?vue&type=template&id=6fb8108a&scoped=true 749 bytes {0} [built]
[13] ./app/javascript/app.vue?vue&type=style&index=0&id=6fb8108a&scoped=true&lang=css 896 bytes {0} [built]
+ 5 hidden modules
ERROR in ./node_modules/babel-loader/lib??ref--1-0!./node_modules/vue-loader/lib??vue-loader-options!./app/javascript/app.vue?vue&type=scr
ipt&lang=js
Module build failed: ReferenceError: [BABEL] /Users/hogehoge//app/javascript/app.vue: Unknown option: base.omit. C
heck out http://babeljs.io/docs/usage/options/ for more information about options.
A common cause of this error is the presence of a configuration options object without the corresponding preset name. Example:
Invalid:
`{ presets: [{option: value}] }`
Valid:
`{ presets: [['presetName', {option: value}]] }`
For more detailed information on preset configuration, please see https://babeljs.io/docs/en/plugins#pluginpresets-options.
at Logger.error (/Users/hogehoge/node_modules/babel-core/lib/transformation/file/logger.js:41:11)
at OptionManager.mergeOptions (/Users/hogehoge/node_modules/babel-core/lib/transformation/file/options/option
-manager.js:226:20)
at OptionManager.init (/Users/hogehoge/node_modules/babel-core/lib/transformation/file/options/option-manager
.js:368:12)
at File.initOptions (/Users/hogehoge/node_modules/babel-core/lib/transformation/file/index.js:212:65)
at new File (/Users/hogehoge/node_modules/babel-core/lib/transformation/file/index.js:135:24)
at Pipeline.transform (/Users/hogehoge/node_modules/babel-core/lib/transformation/pipeline.js:46:16)
at transpile (/Users/hogehoge/node_modules/babel-loader/lib/index.js:50:20)
at Object.module.exports (/Users/hogehoge/node_modules/babel-loader/lib/index.js:173:20)
# ./app/javascript/app.vue?vue&type=script&lang=js 1:0-172 1:193-362
# ./app/javascript/app.vue
# ./app/javascript/packs/hello.js
ERROR in ./node_modules/extract-text-webpack-plugin/dist/loader.js??ref--1-0!./node_modules/style-loader??ref--4-1!./node_modules/css-load
er??ref--1-2!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib??ref--1-3!./node_modules/vue-loade
r/lib??vue-loader-options!./app/javascript/app.vue?vue&type=style&index=0&id=6fb8108a&scoped=true&lang=css
Module build failed: ValidationError: Style Loader Invalid Options
options['ident'] is an invalid additional property
# ./app/javascript/app.vue?vue&type=style&index=0&id=6fb8108a&scoped=true&lang=css 1:0-439 1:460-896
# ./app/javascript/app.vue
# ./app/javascript/packs/hello.js
Child extract-text-webpack-plugin node_modules/extract-text-webpack-plugin/dist node_modules/css-loader/index.js??ref--1-2!node_modules/vu
e-loader/lib/loaders/stylePostLoader.js!node_modules/postcss-loader/lib/index.js??ref--1-3!node_modules/vue-loader/lib/index.js??vue-loade
r-options!app/javascript/app.vue?vue&type=style&index=0&id=6fb8108a&scoped=true&lang=css:
[0] ./node_modules/css-loader??ref--1-2!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/lib?
?ref--1-3!./node_modules/vue-loader/lib??vue-loader-options!./app/javascript/app.vue?vue&type=style&index=0&id=6fb8108a&scoped=true&lang=c
ss 789 bytes {0} [built]
+ 1 hidden module
If you have any advice that would be so helpful.

Webpack - CSS not applied

I have decided to give it a try to Webpack 2. I'm trying to bundle js and css.
The problem is that CSS in not being applied the elements on the page (it is present in the built file).
This is the app structure:
app
|-styles.css
|-app.js
build
|-bundle.js
index.html
webpack config file:
var path = require('path');
module.exports = {
entry: './app/app.js',
output: {
filename: 'bundle.js',
path: path.resolve(__dirname, 'build')
},
module: {
rules: [
{
test: /\.css$/,
use: 'css-loader'
}
]
}
}
index.html:
<html>
<head>
<script src="./build/bundle.js"></script>
</head>
<body>
<div class="abc"> hello </div>
</body>
app.js:
require('./styles.css');
console.log('js loaded!');
When I run build command getting this output:
[0] ./app/styles.css 240 bytes {0} [built] [1] ./~/css-loader/lib/css-base.js 1.51 kB {0} [built] [2] ./app/app.js 148 bytes {0} [built]
Also I can see the css is included in the bundle.js file
exports.push([module.i, ".abc {\r\n width: 300px;\r\n height: 100px;\r\n background-color: red;\r\n}", ""]);
If I include css file in html it works fine so I guess there is no spelling mistake in CSS itself. I spent quite a lot of time trying to figure it out. Is there anything I'm missing?
You're loading the CSS as a string with just css-loader. You'll need style-loader as well in order to have the CSS load into the DOM when you import it.
use: [ 'style-loader', 'css-loader' ]

Split vendor libraries into multiple chunks with webpack

I'd like to split my vendor code into two chunks, one that contains all angular libraries, and another that contains everything else.
My angular app has a single entry point and is setup something like:
entry: {
app: './path_to/app.js',
vendor: ['jquery', 'moment', 'numeral'],
'vendor.angular': ['angular', 'angular-route', 'angular-numeraljs']
}
I then use the CommonsChunkPlugin to configure the two other bundles:
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
chunks: ['app'],
warnings: false,
filename: 'vendor.bundle.js'
})
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor.angular',
chunks: ['app'],
warnings: false,
filename: 'vendor.angular.bundle.js'
})
This generates 3 files:
Version: webpack 1.13.1
Time: 12719ms
Asset Size Chunks Chunk Names
app.bundle.js 19.2 kB 0 [emitted] app
vendor.bundle.js 484 kB 1 [emitted] vendor
vendor.angular.bundle.js 652 kB 2 [emitted] vendor.angular
[0] multi vendor.angular 124 bytes {2} [built]
[0] multi vendor 88 bytes {1} [built]
+ 124 hidden modules
app.bundle.js contains just my app code.
vendor.bundle.js contains all 3rd party libs excluding angular stuff
vendor.angular.bundle.js contains all angular stuff AND all my 3rd party libs that are already inside of vendor.bundle.js.
Is there anyway to have JUST the angular modules bundled in vendor.angular.bundle.js, without automatically including the other 3rd party libs?
Figured this out:
The order of the CommonsChunkPlugin's matter in the plugins array.
To get the desired 'chunking', here's the change I had to make:
Re-order the CommonsChunkPlugins so that the angular chunk was
first.
Update the 'vendor' config below to use 'vendor.angular' in the 'chunks' array.
The updated CommonsChunkPlugins now looks like:
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor.angular',
chunks: ['app'],
warnings: false,
filename: 'vendor.angular.bundle.js'
})
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
chunks: ['vendor.angular'],
warnings: false,
filename: 'vendor.bundle.js'
})
The above now yields:
Version: webpack 1.13.1
Time: 7451ms
Asset Size Chunks Chunk Names
app.bundle.js 19.2 kB 0 [emitted] app
vendor.bundle.js 484 kB 1 [emitted] vendor
vendor.angular.bundle.js 221 kB 2 [emitted] vendor.angular
[0] multi vendor.angular 124 bytes {2} [built]
[0] multi vendor 88 bytes {1} [built]
+ 124 hidden modules
Running:
webpack --progress --display-modules --display-chunks -v
I'm able to verify that all angular related modules are now in the vendor.angular.bundle.js, and all non-angular modules are indeed in vendor.bundle.js

Webpack production build does not load anything

I've been working on an app using React and Webpack for a little while. My development environment works fine, and everything loads properly using webpack-dev-server.
I decided to run a production build of the application to see what the end-product might look like size-wise and observe the general output of the webpack product build.
It turns out that running webpack -p, while it does produce output (more on that in a minute), does not load anything at all when I hit the site in a browser.. A quick check of the output tells me that none of my component code is making it into the webpack -p build.
The images and HTML copy over as they exist in my src (dev) folder, however my JS bundle output is extremely small - the file (main.js) is only 246 bytes.
Here is the output from running webpack -p
$ npm run build
> project#0.1.0 build /Users/me/Development/project
> NODE_ENV=production webpack -p --bail --progress --config webpack.config.babel.js
Hash: 9e5f6974ce21c920a375
Version: webpack 1.12.10
Time: 2003ms
Asset Size Chunks Chunk Names
index.html 1.45 kB [emitted]
images/edit.svg 524 bytes [emitted]
images/search.svg 1.19 kB [emitted]
main.js 246 bytes 0, 1 [emitted] javascript, html
+ 219 hidden modules
When I run the development version of the project, the output is markedly different... I know that the dev server dependencies are in there, and the code is not minified.. And, most importantly - everything works as expected when running the dev server.
$ npm start
> project#0.1.0 start /Users/me/Development/project
> webpack-dev-server --hot --display-modules --config webpack.config.babel.js
http://localhost:3333/
webpack result is served from /
content is served from /Users/me/Development/project/dist
Hash: 1b34ed58f9e323966ada
Version: webpack 1.12.10
Time: 2745ms
Asset Size Chunks Chunk Names
index.html 1.45 kB [emitted]
images/edit.svg 524 bytes [emitted]
images/search.svg 1.19 kB [emitted]
main.js 1.54 MB 0, 1 [emitted] html, javascript
Here's my webpack.config.babel.js file:
import webpack from 'webpack';
import path from 'path';
import ModernizrWebpackPlugin from 'modernizr-webpack-plugin';
import modernizrConfig from './modernizr.config';
const appDir = path.resolve(__dirname, './src');
const distDir = path.resolve(__dirname, './dist');
const nodeModulesDir = path.resolve(__dirname, './node_modules');
const excludeDirs = /(node_modules|bower_components)/;
module.exports = {
entry: {
javascript: appDir + '/main.js',
html: appDir + '/index.html'
},
output: {
path: distDir,
filename: 'main.js',
},
devServer: {
contentBase: distDir,
inline: true,
port: 3333
},
resolve: {
extensions: ['', '.js', '.es6'],
modulesDirectories: [
'node_modules',
'./src'
]
},
plugins: [
// new webpack.optimize.CommonsChunkPlugin('common.js'),
// new ModernizrWebpackPlugin(modernizrConfig),
],
sassLoader: {
sourceMap: false,
includePaths: [
appDir,
nodeModulesDir,
nodeModulesDir + '/breakpoint-sass/stylesheets/',
nodeModulesDir + '/susy/sass'
]
},
module: {
loaders: [
{ // js/jsx
test: /\.js?$/,
exclude: excludeDirs,
loader: 'babel',
query: {
cacheDirectory: true,
presets: [
'es2015', 'react'
]
}
},
{ // html
test: /\.html$/,
exclude: excludeDirs,
loader: 'file?name=[name].[ext]'
},
{ // images
test: /\.(gif|png|jpg|jpeg|svg)$/,
exclude: excludeDirs,
loader: 'file?name=images/[name].[ext]'
},
{ // sass
test: /\.scss$/,
exclude: excludeDirs,
loader: 'style!css!sass'
}
]
}
}
I don't think I've got a particularly complex, or uncommon setup, and I've tried changing everything from es2015/es6 to commonJS already as well, with the same result.
I'm at a loss as to what the issue could possibly be here; hoping that someone can point out some obvious error I've got, or perhaps suggest config updates/changes that could resolve this problem.
Thanks for taking the time to read everything!
As I mentioned in my comment, I've been using webpack successfully for months now, and I've never come across using an HTML file as an entry point.
Usually you'll use Webpack to package up javascript, css, and sometimes images (ie: "assets") to be used by an html file. Serving that HTML file is outside the realm of Webpack's responsibility.
I would suggest using Webpack to generate only the final javascript bundle, then using some other method (ie: express, or some other web server) to serve that file and the html that consumes it.

Categories