Webpack Exclude folder - javascript

I'm shoving a rather large app through Webpack, which pulls from two library folders: thirdparty and node_modules. I've setup my rule for js files as such:
{
test: /\.js$/,
loader: 'babel-loader',
include: [
/src\/js\/client/
],
exclude: [
/node_modules/,
/thirdparty/
]
}
My hope was that webpack wouldn't parse any folders under either of those two directories, but I'm getting errors for libraries that are. For instance:
WARNING in ./~/durandal/js/system.js
51:8-15 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
WARNING in ./~/durandal/js/system.js
52:8-15 Critical dependency: require function is used in a way in which dependencies cannot be statically extracted
ERROR in ./~/durandal/js/system.js
Cannot statically analyse 'require(..., ...)' in line 278
# ./src/js/client/lib/durandal/overrides/views.js 2:0-37
# ./src/js/client/index.js
Am I misunderstanding the functionality of include/exclude, or is this a bug with Webpack?

The rules do not decide which files are being parsed by webpack, but instead they are only applied to the files which are included and also satisfy the condition. Even if you had no rule at all, webpack would still parse the same files since you imported them somewhere.
You can exclude modules from being bundled with the externals option. These externals will have to be present at runtime in some way (for example loaded in a <script> tag).
If you just want webpack not to parse the files, but still include them, you can configure module.noParse. But as the documentation says, they should not contain any imports.

Related

Prevent webpack 4 pug loader from compiling mixin files

I'm really new to Webpack 4 and found a configuration issue I can not resolve.
I'm configuring Webpack for a multi page application. HTML template engine is PUG.
Files are compiled correctly, but when I create the bundle, Webpack is also compiling the mixins I have at "src/pug/mixins" folders. Therefore I get an .html file from every .pug mixin file I have.
How can I tell Webpack not to generate an .html file from a mixins located inside a folder?
I have the following at my webpack.config file:
module: {
rules: [
{
test: /\.pug$/,
use: ["pug-loader"],
exclude: [path.resolve(__dirname, 'src/pug/utils')]
},
However, all mixins inside utils folder are converted (i.e: utils/coreMixins.pug -> utils/coreMixins.html )
Thanks for your answers

What webpack4 loader is used to load *.svg files, *.gif, *.eot?

I'm developing a react UI component and it depends on another UI component (react-widgets/lib/DropDownlist). This javascript module has resources that end with these file extensions: *.gif, *.eot, *.svg, *.woff, *.ttf.
Webpack4 is complaining that it doesn't know how to process these file types and that I might need a loader to handle these file type. One error is:
Error in .../react-widgets/dist/fonts/rw-widgets.svg?v=4.1.0
Module parse failed: ...
**You may need an appropriate loader to handle this file type.**
So I need to update my webpack.config.js file with the appropriate loaders for those file types. My config is based off of this. Side Note: A
shout out goes to Mark England who wrote this article which does a fantastic job for how to create a reusable component.
The relevant snippet is:
// Snippet from Mark's code webpack.config.js
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: "babel-loader",
exclude: /node_modules/
},
{
test: /\.css$/,
use: ["style-loader", "css-loader"]
}
]
},
I know what the syntax for webpack is to define the loaders but I don't know what loaders to use. But this sample webpack config file didn't include support for these other file types.
What have I done to try and solve the problem
I generally use create-react-app so I avoid this problem altogether. :-) It, however, doesn't allow me to create react libraries for distribution (AFAIK).
First I searched on the net webpack *.gif loader. Nothing useful.
Next I searched for webpack loaders based on file type. This gave some good results that describe the loader syntax, pointed me to some loaders file-loader and how to use them, and this question on SO that helps me realize the *.svg loader might be what I need to load svg files.
{test: /\.svg$/, use: "svg-inline-loader"},
So I might be able to use svg-inline-loader for the *.svg files.
I can repeat this approach for all of the file types.
The next approach is to examine Create React App (CRA)
I primarily develop in react, and look at the CRA webpack config files (because the create-react-app appears to stay leading edge on these topic). So I can see the url-loader is used for images (based on what the node_modules/react-scripts/config/webpack.config.dev.js file is using).
Another one down...
My question
Does webpack (or another website) have a table that lists the loaders available for given file types?
For example,
know good image loaders for the following file types are:
Webpack 4
*.gif, *.jpg => url-loader
*.svg => svg-inline-loader
*.eot => ???
I realize that because webpack is more of a plugin/loader architecture that it might not be webpacks place to have this list so another website might need to have it.
When you need a loader what do you do?
If there is no central place to look for this answer, then please share how you find loaders that are needed to solve your webpack file loading problem.
It all depends on your workflow, how u want to load assets at run-time.
For eg, if u have lot of images, it might be a good idea to use a file-loader and place them directly inside the build directory.
The above approach will increase the GET calls and the bundled js file size will not be affeted
If u have less images/small size images then you can use url-loader which converts them into data-URL and put them inside your bundled js files.
The above approach will reduce the GET calls and will slightly increase the bundled js size.
If u want combination of both, then u can set a size limit and fallback loader(file-loader) on url-loader. What this will do is, the size of the dataURL will be calculated.If the size is grater than the limit, the file-loader will be used, which will place it in the build directory.
How I use them
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
outputPath: 'images/',
name: '[name][hash].[ext]',
},
},
],
},
{
test: /\.(svg)$/,
exclude: /fonts/, /* dont want svg fonts from fonts folder to be included */
use: [
{
loader: 'svg-url-loader',
options: {
noquotes: true,
},
},
],
},
{
test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
exclude: /images/, /* dont want svg images from image folder to be included */
use: [
{
loader: 'file-loader',
options: {
outputPath: 'fonts/',
name: '[name][hash].[ext]',
},
},
],
}

Webpack - ignore loaders in require()?

I have a TypeScript project which I am bundling with Webpack. It is a demo/docs app for an open source lib I am writing, so I want to show some of the source code as part of the docs.
In my webpack config I have:
loaders: [
{ test: /\.ts$/, loader: 'ts'},
{ test: /\.css$/, loader: 'style!raw' },
{ test: /\.html/, loader: 'html' }
]
which works fine for transpiling and bundling my TypeScript files. In one of my app components I do this:
basicCodeT: string = require('./basic-example-cmp.html');
basicCodeC: string = require('!raw!./basic-example-cmp.ts');
to load the source code into a string which I then want to display in the docs.
As you can see, there is a leading ! in the second line which I discovered seems to "bypass" the default loaders from the config and loads the raw TypeScript as a string.
In my dev build this works, but when I do a "production" build with the UglifyJsPlugin and OccurrenceOrderPlugin, I get the following output:
ERROR in ./demo/src/basic-example-cmp.html
Module build failed:
# ./demo/src/demo-app.ts 24:26-61
which corresponds to the line in the source where I try to require the raw TypeScript.
So, I want to pass basic-example-cmp.ts through the TS compiler as part of the app build, but also want to require it as raw text in the app.
My question then is: Is there a proper way to tell webpack to "ignore" loaders in specific require cases?
Is my way of prepending a ! correct? Is it a hack?
Update
Turns out my problem is simply due to the way Webpack handles HTML templates - it does not like the Angular 2 template syntax, see: https://github.com/webpack/webpack/issues/992
You can add two exclamation to ignore loaders in the webpack config file
!!raw!file.ts
one exclamation will only disable preloaders!
https://webpack.js.org/concepts/loaders/#inline
As far as I know that is the only way you are going to be able to load a file in two different ways. I expect the issue is that your paths are different in your production build.
I would suggest running webpack with the --display-error-details flag to get more info on why it fails.
Is there a proper way to tell webpack to "ignore" loaders in specific require cases?
Yes. Update your test in { test: /\.ts$/, loader: 'ts'}, as desired.

Load requirejs module's css dependency with webpack

I am using webpack and I need to include some libraries built for requirejs.
Everything worked fine until one of the library declared a css dependency:
define(["css!./stylesheet.css"], function(){ \* module *\ });
Webpack has a css loader too, however it does not load them automatically as requirejs's one does. One must pipe the css loader to the style loader to do so:
require("style!css!./stylesheet.css");
Is there any way to make the prior working? For example, can I overwrite the css loader for this particular library so that it is piped with the style loader ?
I found a nice solution using postLoaders.
Adding
postLoaders: [
{ test: /\.css$/, loader: 'style', include: path.join(__dirname, "pathTo/theLib") }
]
into the module property of the webpack config did the trick.

Importing CSS files in Isomorphic React Components

I have a React application with Components written in ES6 - transpiled via Babel and Webpack.
In some places I would like to include specific CSS files with specific Components, as suggested in react webpack cookbook
However, if in any Component file I require a static CSS asset, eg:
import '../assets/css/style.css';
Then the compilation fails with an error:
SyntaxError: <PROJECT>/assets/css/style.css: Unexpected character '#' (3:0)
at Parser.pp.raise (<PROJECT>\node_modules\babel-core\lib\acorn\src\location.js:73:13)
at Parser.pp.getTokenFromCode (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:423:8)
at Parser.pp.readToken (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:106:15)
at Parser.<anonymous> (<PROJECT>\node_modules\babel-core\node_modules\acorn-jsx\inject.js:650:22)
at Parser.readToken (<PROJECT>\node_modules\babel-core\lib\acorn\plugins\flow.js:694:22)
at Parser.pp.nextToken (<PROJECT>\node_modules\babel-core\lib\acorn\src\tokenize.js:98:71)
at Object.parse (<PROJECT>\node_modules\babel-core\lib\acorn\src\index.js:105:5)
at exports.default (<PROJECT>\node_modules\babel-core\lib\babel\helpers\parse.js:47:19)
at File.parse (<PROJECT>\node_modules\babel-core\lib\babel\transformation\file\index.js:529:46)
at File.addCode (<PROJECT>\node_modules\babel-core\lib\babel\transformation\file\index.js:611:24)
It seems that if I try and require a CSS file in a Component file, then the Babel loader will interpret that as another source and try to transpile the CSS into Javascript.
Is this expected? Is there a way to achieve this - allowing transpiled files to explicitly reference static assets that are not to be transpiled?
I have specified loaders for both .js/jsx and CSS assets as follows:
module: {
loaders: [
{ test: /\.css$/, loader: "style-loader!css-loader" },
{ test: /\.(js|jsx)$/, exclude: /node_modules/, loader: 'babel'}
]
}
View the full webpack config file
FULL DETAILS BELOW:
webpack.common.js - A base webpack config I use, so I can share properties between dev and production.
Gruntfile.js - Gruntfile used for development. As you can see it requires the webpack config above and adds some development properties to it. Could this be causing the problem?
Html.jsx - My HTML jsx component that tries to import/require the CSS. This is an isomorphic app (using Fluxbile), hence needing to have the actual HTML as a rendered component. Using the require statement seen in this file, in any part of my application, gives the error described.
It seems to be something to do with grunt. If I just compile with webpack --config webpack.common.js then I get no errors.
Short answer: It's a node runtime error. Trying to load CSS on the server in isomorphic apps is not a good idea.
You can't require css in the component that you are rendering on the server. One way to deal with it is to check if it's a browser before requiring css.
if (process.env.BROWSER) {
require("./style.css");
}
In order to make it possible you should set process.env.BROWSER to false (or delete it) on the server
server.js
delete process.env.BROWSER;
...
// other server stuff
and set it to true for the browser. You do it with webpack's DefinePlugin in the config -
webpack.config.js
plugins: [
...
new webpack.DefinePlugin({
"process.env": {
BROWSER: JSON.stringify(true)
}
})
]
You can see this in action in gpbl's Isomorphic500 app.
If you're building an isomorphic app with ES6 and want to include CSS when rendering on the server (important so basic styles can be sent down to the client in the first HTTP response) check out the #withStyles ES7 decorator used in React Starter Kit.
This little beauty helps ensure users see your content with styles when the page is first rendered. Here's an example isomorphic app I'm building leveraging this technique. Just search the codebase for #withStyles to see how it's used. It goes a little something like this:
import React, { Component, PropTypes } from 'react';
import styles from './ScheduleList.css';
import withStyles from '../../decorators/withStyles';
#withStyles(styles)
class ScheduleList extends Component {
We had a similar problem with our isomorphic app (and a lot of other problems, you can find details here). As for the problem with CSS import, at first, we were using process.env.BROWSER. Later we've switched to babel-plugin-transform-require-ignore. It works perfectly with babel6.
All you need is to have the following section in your .babelrc
"env": {
"node": {
"plugins": [
[
"babel-plugin-transform-require-ignore", { "extensions": [".less", ".css"] }
]
]
}
}
After that run your app with BABEL_ENV='node'. Like that:
BABEL_ENV='node' node app.js.
Here is an example of how a production config can look like.
You can also try this
https://github.com/halt-hammerzeit/webpack-isomorphic-tools
or this
https://github.com/halt-hammerzeit/webpack-react-redux-isomorphic-render-example
I used this babel plugin with success to solve a similar issue with less, svg and images. But it should work with any non js assets.
It rewrites all assets imports into variables, so as long as you run the compiled code just on the server and have a bundle built with webpack for the client, it should be fine.
The only drawback is that it onlyworks with named imports, so you'll have to:
import styles from './styles.css';
in order to make it work.
Make sure you are using the loaders in your webpack config:
module: {
loaders: [
{ test: /\.jsx$/, exclude: /node_modules/, loader: "babel" },
{ test: /\.css$/, loader: "style!css" }
]
}
You probably have an error in your Webpack config where you're using the babel-loader for all files, and not just .js files. You want to use a css loader for .css files.
But you shouldn't use import for loading any other module than Javascript modules, because once imports are implemented in browsers, you will only be able to import Javascript files. Use require instead in cases where you need Webpack specific functionality.
ORIGINAL POST
Webpack uses require and Babel lets you use import from ES6 which mostly do the same thing (and Babel transpiles the import to a require statement), but they are not interchangable. Webpacks require function lets you specify more than just a module name, it lets you specify loaders as well, which you cannot do with ES6 imports. So if you want to load a CSS file, you should use require instead of import.
The reason is that Babel is just a transpiler for what's coming in ES6, and ES6 will not allow you to import CSS files. So Babel won't allow you to do that either.
I've finally realised that this error is not originating at the compile stage, but rather at runtime. Because this is an ismorphic app, the components and any dependencies they have will first be parsed on the server (ie, in node). It is this that is causing the error.
Thanks for all the suggestions, I will post more if/when I figure out how to have per-component stylesheets in an isomorphic application.
I also met the same problem when I want to do the server-side render.
So I write a postcss plugin, postcss-hash-classname.
You don't require css directly.
You require your css classname js file.
Because all you require is js file, you can do the server-side render as usual.
Besides, this plugin also use your classname and file path to generate unique hash to solve css scope problem.
You can try it!
Solved With This...
https://github.com/michalkvasnicak/babel-plugin-css-modules-transform
$ npm install --save-dev babel-plugin-css-modules-transform
Include plugin in .babelrc
{
"plugins": ["css-modules-transform"]
}
And Import Css..... Like This Anywhere You Want
const styles = require('./test.css');
OR
import css from './styles.css'
Also See This... Apart From Css Files........................................................ .
https://www.npmjs.com/package/babel-plugin-transform-assets

Categories