I am running an Angular 4 project with Webpack 2.4.
For some reason, some of the third party Javascript plugins files are being modified after compilation, and they are shown in the browser's debugger as a very long, one line string:
This is very inconvenient because I can't use Chrome / FF debugger, as I am unable to set up any breakpoint in there.
Following some of the already posted questions in this site and many others, I extracted the webpack.config.js file by executing ng eject
The section where the js files are imported look as follows:
{
...
"scripts": [
...
"script-loader!./node_modules/handsontable-pro/dist/handsontable.full.js",
...
],
"styles": [
...
]
},
"output": {
"path": path.join(process.cwd(), "dist"),
"filename": "[name].bundle.js",
"chunkFilename": "[id].chunk.js"
}
The file handsontable.full.js does not look like that in my project's folder. It seems to be pretty structured. It seems to suffer some kind of modification when the application is built and served.
More puzzling, many other files in the node_modules folder do not have the same problem.
Now, I tried to tweak the webpack.config.js, as suggested in many forums, specifically SourceMapDevToolPlugin, but with very little luck.
So, several questions arise here:
What is happening here? The transformed file doesn't seem to be a minified file, or a hashed file... What is it?
How can I prevent this from happening, so I can set up breakpoints in that file and use the browser's debugger for tracing, var inspect, etc.
Check the devtool: property in the Webpack config object. If it's set to eval, cheap-eval-source-map (or something like it, don't remember all the eval options), try changing it to source-map or cheap-source-map.
Full list of options here: https://webpack.js.org/configuration/devtool/
Related
I am currently writing a plugin for obsidian.md that renders math functions inside a code block. I used webpack for bundling node libraries like yaml and function-plot. In the config, I added 'obsidian' as an external. The plugin builds with a warning about the bundle size but that doesn't matter since it's local anyways. When I add the plugin, it always says ''obsidian' not defined'. I guess it's looking for obsidian in the global context and can't find it? Here's the repo: https://github.com/leonhma/obsidian-functionplot
Do you know how to configure webpack properly? There's probably some really easy fix but I'm also new to typescript, webpack and developing plugins for obsidian..
Thank you #håkon-hægland for your suggestion (why didn't I think of that?). First of all, the file generated by webpack looked like
function(obsidian) {
... (around 300kb code)
}(obsidian);
, so webpack tried to access some global object called 'obsidian'. The important part in webpack.config.js was
...
externals: [
obsidian: 'obsidian'
],
...
As per your suggestion, i took a look at the other repo, and they use
...
externals: [
obsidian: 'commonjs2 obsidian'
],
...
That fixed my problem and now obsidian is properly imported at runtime. Just posting this in case someone else has this problem, as i couldn't find an existing answer myself.
PS: For those interested, since you are most certainly developing obsidian plugins: It was also really important to set output.libraryTarget to commonjs or commonjs2 inside the webpack config.
I have uninstalled 2 extensions (Auto Comment Blocks and Document This) that I thought they could be responsible, also I deleted the node_modules folder and setup the javascript (three.js) working folder again for intellisence/autocomplete (via types) and still the problem remains.
Here is before and after selecting a variable.
Is there a way to fix this extremely idiotic behavior?
If you copy/paste the code as well as screen-shot I can see what happens in my install.
Did you restart after un-installing the extensions?
Have you run vs code with all extensions disabled? code --disable-extensions
I assume you are using the latest official version?
Do you have typescript checking enabled?
Ironically, although I have the problem for a long time, I instinctively found the answer just after I posted the question:
I put my only two (custom) source files main.js and shaders.js in a 'src' folder, then edited the jsconfig.json file and I changed the exclude reference, in order to exlude all other *.js files in the root folder and added the include.
Now jsdoc comment repeating stopped completely, and as a bonus, intellisence works far better!
from:
"exclude": [
"node_modules"
]
to:
"exclude": [
"node_modules",
"**/node_modules/*",
"*.js"
]
"include": [
"src/*.js"
]
EDIT: Or include alone, as Sumomo suggested in the comments.
The HTML starter kit pro for Durandal contains the following grunt task for optimizing a build:
durandal: {
main: {
src: ['app/**/*.*', 'lib/durandal/**/*.js'],
options: {
name: '../lib/require/almond-custom',
baseUrl: requireConfig.baseUrl,
mainPath: 'app/main',
paths: mixIn({}, requireConfig.paths, {
'almond': '../lib/require/almond-custom.js'
}),
exclude: [],
optimize: 'none',
out: 'build/app/main.js'
}
}
}
I have some concerns about it which I need your help sorting out:
Script file redundancy. The build process keeps the lib folder with scripts like jQuery, bootstrap etc. Why? If you look at the built build/app/main.js is has added all those scripts. Which leads me to the following question:
If I remove the lib folder, everything works, except for the fact that I get a require is not defined in the console. The code still looks for lib/require/require.js which can be solved by simply adding it there. However, isn't this what almond is all about? It's included in the built build/app/main.js file. As far as I knew, Almond is a light weight replacement for require to be used in optimized files.
To reproduce the issues you can simply run the "Quick start" provided in the link at the top.
Yes, You are right that main.js includes everything needed to run the app. The reason You are getting require is not defined is because, if you closely look at the index.html file you will see that the index.html refers looks for the file in /lib/require folder and loads our main.js file through it. there is another line right below that in index.html which is commented, you can just uncomment that and it should just work even if you remove lib directory.
The only errros that you will get by removing the /lib directory after uncommenting <script src="app/main.js"></script> line and commenting <script src="lib/require/require.js" data-main="app/main"></script>.
Hope it helps.
What's coming? (1) Short background. (2) Question. (3) Detail (short; file listings just long enough to show relevant information). (4) Question again.
Short background: I want to deploy my web site using webpack. webpack is looking for style-loader and css-loader in the wrong directories, so my builds aren't completing.
Question
Is there a way I can change any of the files shown here to deploy with webpack?
Detail
environment
Windows 10 Home -64, up-to-date/ Toshiba Satellite with AMD A6
Node v6.2.0/ webpack v1.13.2
relevant files and directory structure
C:\Dev\example\example.js
C:\Dev\example\bluebird.js
C:\Dev\example\jquery.js
C:\Dev\example\img\image1.jpg
C:\Dev\example\img\image2.jpg
C:\Dev\example\img\svg1.svg
C:\Dev\example\built\package.json
C:\Dev\example\built\webpack.config.js
C:\Dev\example\built\index1.html
C:\Dev\example\built\index2.html
C:\Dev\example\built\example.bundle.js
C:\Dev\example\built\[hash1].jpg
C:\Dev\example\built\[hash2].jpg
C:\Dev\example\built\[hash3].svg
C:\Dev\node-modules\webpack
C:\Dev\node-modules\css-loader
C:\Dev\node-modules\file-loader
C:\Dev\node-modules\html-loader
C:\Dev\node-modules\style-loader
C:\Dev\node-modules\uglify-js
C:\Dev\node-modules\url-loader
C:\Dev\example\built\package.json
{
"name": "example",
"version": "0.0.1",
"description": "example",
"main": "example.bundle.js",
"author": "Bald Eagle"
}
call to webpack: I call webpack at the command prompt from C:\Dev\example\built with one line (two here for your convenience)
node C:\Dev\node_modules\webpack\bin\webpack.js -p --display-reasons
--display-error-details --display-modules --profile
C:\Dev\example\built\webpack.config.js
"use strict"
let path = require("path")
let webpack = require("webpack")
let preferEntry = true // for OccurrenceOrderPlugin
module.exports = {
context: "C:/Dev/example/built",
entry: [
"./index1.html",
"./../jquery.js",
"./../bluebird.js",
"./../example.css"
],
output: {
path: "C:/Dev/example/built",
filename: "./example.bundle.js",
publicPath: "http://www.example.com"
},
module: {
loaders: [
{
test: /\.(?:gif|jpg|jpeg|svg)$/,
loader: "file!url"
},
{
test: /\.html$/,
loader: "html"
},
{
test: /\.png$/,
loader: "url-loader?mimetype=image/png"
},
{
test: /\.css$/,
loader: "style-loader!css-loader"
} ],
plugins: [
new webpack.optimize.UglifyJsPlugin({minimize: true}),
new webpack.ProvidePlugin({
'window.jQuery': 'jquery',
'window.$': 'jquery',
}) ] },
resolve: {
root: path.resolve("./index1.html"),
modulesDirectories: ["node_modules", "built"],
fallback: "C:/Dev"
},
resolveLoader: {
fallback: "C:/Dev",
modulesDirectories: ["node_modules"]
}
}
C:\Dev\example\built\index1.html: My goal for this HTML file is to point webpack the right direction to collect all information for the web site into its example.bundle.js file. I shortened one long line (clip) and excluded irrelevant lines, including the entire body.
<!doctype html>
<html>
<head>
<script src="./../example.js"></script>
<link href="./../example.css" rel="stylesheet" type="text/css" />
<link href="https://fonts.googleapis.com/css? (clip) type="text/css" />
<script src="./../jquery.js"></script>
<script src="./../bluebird.js"></script>
</head>
<body>
</body>
</html>
feedback from webpack
It outputs routine information about building pieces of example.bundle.js (represented with ...), except these: (I added any double asterisks **; I broke some long lines and indented the later parts of such lines.)
...
[9] ./../example.css 919 bytes {0} [built] [**2 errors**]
single entry ./../example.css [0] multi main
WARNING in ./example.bundle.js from UglifyJs
...
Condition always false [C:/Dev/~/style-loader!
C:/Dev/~/css-loader!**./../example.css:10,0**]
Dropping unreachable code [C:/Dev/~/style-loader!
C:/Dev/~/css-loader!**./../example.css:12,0**]
Side effects in initialization of unused variable update
[C:/Dev/~/style-loader!C:/Dev/~/css-loader!
**./../example.css:7,0**]
**ERROR** in ./../example.css
Module not found: Error: Cannot resolve 'file' or 'directory'
./../node_modules/css-loader/index.js in
C:/Dev/example/built\..
resolve file
**C:/Dev/example/built\node_modules\css-loader\index.js
doesn't exist**
[plus more similarly inaccurate variants; it should be looking
for C:\Dev\node_modules\css-loader\index.js; it's there]
...
**ERROR** in ./../example.css
Module not found: Error: Cannot resolve 'file' or 'directory'
./../node_modules/style-loader/addStyles.js in
C:/Dev/example/built\..
resolve file
**C:/Dev/example/built\node_modules\style-loader\addStyles.js.webpack.js
doesn't exist**
[plus more similarly inaccurate variants]
...
With the double asterisks, I wanted to highlight that webpack outputted that there'd be two errors and outputted the two errors. Also, I wanted to highlight the cited points of error in css. Those lines are below.
C:\Dev\example\example.css: I show only the first twelve lines because of the lines webpack cited as errors; I added line numbers.
1 /* example web site
2 * blah
3 * blah
4 * blah
5 * blah
6 * blah
7 *
8 * Version
9 */
10
11 /* defaults */
12 body, div {
My conclusion: The points webpack cited are not points of error. Maybe the points cited apply to a minified version of the file. Or to some code.
Problem when I point a browser to index1.html above: All content and rendering are fine; JavaScript isn't enabled. (Consistent with not processing css correctly?)
C:\Dev\example\built\index2.html: My goal for this HTML file is to use the same webpack techniques I'll use in the index.html that will be on the web server. I changed this the same ways I changed index1.html.
<!doctype html>
<html>
<head>
<script src="./example.bundle.js"></script>
<link href="https://fonts.googleapis.com/css? (clip) type="text/css" />
</head>
<body>
</body>
</html>
Problem when I point a browser to index2.html immediately above: All content shows (including the three images), but (1) JavaScript isn't enabled and (2) there's no effect from css (no colors or positioning, etc.) (Consistent with not processing css correctly?)
Question
Is there a way I can change any of the files shown here to deploy with webpack?
Thanks for taking the time to read. Thanks in advance for any responses.
Need more detail? I'll provide it if I can.
It seems like you've set up your project in a very unusual style for Node.js development which makes your setup more complicated than it needs to be. I'm not sure if that is a hard requirement, but since you've not mentioned it to be required, I'm assuming you are allowed to change your directory structure.
Use local dependencies
In Node.js, all dependencies are installed separately for each project. It enables you to use different versions of a dependency while working on different projects without the need to switch these dependencies manually. You should put the package.json in the root folder of your project (I assume C:\Dev\example in your case) and then run npm install webpack css-loader style-loader --save-dev. NPM is the package manager for Node.js that comes pre-bundled with the executable so it should already be installed on your system. After running npm install you should see a node_modules folder which contains all these project-specific dependencies. You should not commit these dependencies to your version control system because they may contain platform-specific binaries that are not usable on different machines. Every developer in this project needs to run npm install first.
Configure your common commands under scripts
NPM provides the possibility to add common commands as scripts to your package.json. This way, other developers (including "Future You") only need to remember npm run some-script instead of all the command-line options. One little known feature of NPM is, that it prepends ./node_modules/.bin to your $PATH on runtime which means that inside scripts you can reference any executable installed in your local node_modules just as if it was installed globally. Thus you only need to write:
"scripts": {
"start": "webpack --config ./path/to/webpack.config.js"
}
and it will use your local webpack installation. As a side-note: It's best-practice to provide a "start" script. It can be called by just running npm start.
Your webpack config
Your webpack config looks ok, but I have some advice:
You should separate between your development stuff and the actual build. Usually, the webpack.config.js is placed in the root of your project because then you just need to run webpack and webpack will look for a config in the current directory. Then, you should have a src or app folder which contains all the development files, including the index HTML files as you've mentioned. At last, you create a build folder which is completely wiped before a build. This way, your build does not contain any obsolete files.
Do not use absolute paths in your webpack.config. It makes sharing your project a lot harder – including "Future You" that moves the project to another directory. Use the Node.js builtin path module and the special module variable __dirname to resolve absolute paths. You can also use require.resolve to use Node's resolving algorithm.
Do not set the context and the publicPath option unless you know what you are doing. Given from the information you've provided, I doubt that these options are necessary here.
Since you've installed all the dependencies locally, you should remove all the resolving options because it should work out-of-the-box now.
Although it is permitted, you should not omit the -loader postfix in your loader configurations. It can lead to hard-to-understand errors when you have a css or html module in your node_modules just by coincidence.
The problem with index.html files
webpack is a JavaScript bundler. That's why you need to have a css- or an html-loader if you want to include HTML or CSS. These loaders transform HTML or CSS into a JavaScript module by transforming the text contents into strings that are exported. This has some nice advantages like hot module replacement or CSS modules. But it also means that you can't use an HTML or CSS file as the only entry point to your website. Every HTML and CSS will eventually be translated to JavaScript. This trade-off is ok for single-page applications where you need JS anyway, but it is probably surprising for everyone who tries to use webpack on a static site.
Since you're not the first one with this problem, several solutions have already emerged. My recommendation is to use the HTML Webpack Plugin in combination with the Extract Text Webpack Plugin.
The Extract Text Webpack Plugin can be used to extract static JS strings out of the bundle into a speparate file. This is exactly what you need to remove CSS from the JS bundle.
The HTML Webpack Plugin creates an index HTML file that includes all the generated JS and CSS files. Out of the box, it will just generate an HTML file with no contents (often referred to application shell which is typical for single-page applications). Since you already have content in your index HTML files, you need to configure your HTML files as templates. You'll need to add a plugin for each HTML file.
These plugins work pretty well, but this setup is already pretty complex. You should decide if you want to use webpack just for JS or also for HTML and CSS.
I'm trying to minify and concatenate require modules together into one file.
For example, if I have a file called article.js like the following:
define(["jquery","flexslider","share_div"],function(){});
I want all of those dependencies to be combined and minified into one file.
I have the following in my build script, but it's not combining files together, just minifying.
This is my build.js file:
{
"appDir": "../js",
"baseUrl": "../js",
"dir": "../www-build",
"mainConfigFile": "../js/common.js",
"modules": [
{
"name": "common"
},
{
"name": "page/article",
"exclude": ["common"]
}
],
"paths": {
"jquery": "empty:",
"jquery_ui": "empty:",
"twitter_bootstrap": "empty:"
}
}
My understanding of Require and the build script may be wrong, but I envisioned that files would be concatenated together.
Any guidance would be appreciated.
To also minify the nested dependencies of the individual modules that are traced as dependencies, specify this additonal property as part of your build file: findNestedDependencies: true. (See line 318-324 of the full RequireJS doc.)
This is if articles.js is a dependency found in common.js and you are tracing through common.js to build a concatenated and minfied file. I am not sure about the lack of concatenation if you are just trying to build the individual module itself.
The build.txt file you've included in a comment (the comment I'm referring to has been deleted by Andy after I wrote my answer) is a bit hard to read since it has not been included as preformatted code. From what I can see in the file you've provided, r.js does indeed concatenate the dependencies of article.js into one file. So it appears that you've solved your original question somehow.
As so why your output is not appearing in the right directory, I can only speculate. The build.js file you've shown in your question is set to put everything in ../www-build, however your build.txt file shows the output being stored in ../js. Here's the speculation part: sometimes when we are in the midst of trying to find solutions, we make changes here and there and lost track of where we were. That certainly happened to me. What I do then is clean my development tree (remove the builds), inspect my build configuration to make sure that what I think is used is indeed used and rerun the build.