{"id":22338,"date":"2015-09-28T13:14:29","date_gmt":"2015-09-28T13:14:29","guid":{"rendered":"https:\/\/blog.jetbrains.com\/webstorm\/?p=7799"},"modified":"2022-10-04T13:36:25","modified_gmt":"2022-10-04T12:36:25","slug":"debugging-webpack-applications-in-webstorm","status":"publish","type":"webstorm","link":"https:\/\/blog.jetbrains.com\/zh-hans\/webstorm\/2015\/09\/debugging-webpack-applications-in-webstorm","title":{"rendered":"Tutorial: Getting Started With Webpack Applications in WebStorm"},"content":{"rendered":"<p><em>Note: This blog post was updated in October 2022.<\/em><\/p>\n<p><a href=\"https:\/\/github.com\/webpack\/webpack\" target=\"_blank\" rel=\"noopener\">Webpack<\/a> is a module bundler. Its main purpose is to bundle JavaScript files for usage in browsers. It\u2019s also capable of transforming, bundling, and packaging most assets and resources.<\/p>\n<p>In this tutorial, we\u2019ll go over how to get started with webpack in WebStorm. We\u2019ll do the following:<\/p>\n<ul>\n<li><a href=\"#create_a_new_webstorm_project\">Create a new WebStorm project and add some code to it<\/a><\/li>\n<li><a href=\"#run_the_application_first_attempt\">Try to run the application and see how webpack may help us<\/a><\/li>\n<li><a href=\"#install_and_configure_webpack\">Install webpack in your project<\/a><\/li>\n<li><a href=\"#create_a_webpack_configuration_file\">Create a webpack configuration file<\/a><\/li>\n<li><a href=\"#build_the_application\">Build the application with webpack<\/a><\/li>\n<li><a href=\"#automate_the_build_procedure\">Automate webpack build in WebStorm<\/a><\/li>\n<li><a href=\"#debug_the_application\">Try to debug the application and see why we need source maps<\/a><\/li>\n<li><a href=\"#generate_source_maps\">Debug the application with source maps<\/a><\/li>\n<\/ul>\n<h2 id=\"create_a_new_webstorm_project\">Create a new WebStorm project<\/h2>\n<p>We\u2019ll start by opening WebStorm and clicking <em>New Project<\/em> on the <em>Welcome<\/em> screen.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_welcome_screen.png\" alt=\"Welcome screen: New Project\" width=\"800\"><\/p>\n<p>In the <em>New Project<\/em> dialog, select <em>Empty Project<\/em> and specify the name of the project. Let\u2019s use <em>my_webpack_app<\/em>. Once you click <em>Create<\/em>, an empty project will be generated and opened in WebStorm.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_new_project_dialog.png\" alt=\"Create app: New Project dialog\" width=\"800\"><\/p>\n<p>Now let\u2019s create the JavaScript files <em>main.js<\/em> and <em>greetings.js<\/em>, and an <em>index.html<\/em> file that references <em>main.js<\/em>.<\/p>\n<p>To create a file, select the project root folder <em>my_webpack_app<\/em>, right-click on it and select <em>New | HTML File<\/em> or <em>New | JavaScript File<\/em> from the context menu.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_new_file-1.png\" alt=\"Create a file\" width=\"800\"><\/p>\n<p>We&#8217;ll start with the <em>index.html<\/em> page. On this page, we&#8217;ll add a <strong>Welcome!<\/strong> button using the following code:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">&lt;body&gt;\n&lt;h1&gt;Hello Webpack!&lt;\/h1&gt;\n&lt;input type=&quot;button&quot; name=&quot;Welcome&quot; id=&quot;welcomeBtn&quot; value=&quot;Welcome!&quot;&gt;\n&lt;div id=&quot;welcomeMsg&quot;&gt;&lt;\/div&gt;\n&lt;script src=&quot;main.js&quot; type=&quot;text\/javascript&quot; &gt;&lt;\/script&gt;\n&lt;\/body&gt;<\/pre>\n<p>Clicking the <strong>Welcome!<\/strong> button calls <em>main.js<\/em>:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">const greeting = require(&quot;.\/greeting.js&quot;);\n(function () {\n\tconst welcomeBtn = document.getElementById(&quot;welcomeBtn&quot;);\n\tconst welcomeMsg = document.getElementById(&quot;welcomeMsg&quot;);\n\twelcomeBtn.addEventListener(&#039;click&#039;,  function(){ greeting(welcomeMsg)});\n})();<\/pre>\n<p><em>Main.js<\/em> then calls <em>greeting.js<\/em>, which displays a <strong>Welcome to WebStorm<\/strong> message:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">function addGreeting (a) {\n    a.innerHTML = &quot;Welcome to WebStorm&quot;;\n}\nmodule.exports = addGreeting;<\/pre>\n<p>You may notice that WebStorm hasn\u2019t resolved <code>module<\/code> and <code>require<\/code>. To fix this, hover over the unresolved code and click <em>Enable coding assistance for Node.js<\/em>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_enable_node_assistance.png\" alt=\"Unresolved code: Enable coding assistance for Node.js\" width=\"800\"><\/p>\n<h2 id=\"run_the_application_first_attempt\">Run the application: first attempt<\/h2>\n<p>Now let\u2019s run our application. Open <em>index.html<\/em> and select <em>Run \u2018index.html\u2019<\/em> from its context menu.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_run_index_html.png\" alt=\"Run index.html from teh context menu\" width=\"800\"><\/p>\n<p>The browser will open showing the home page with a <strong>Hello Webpack!<\/strong> message and a <strong>Welcome!<\/strong> button. But if we click on the button, nothing happens.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_run_click_fails.png\" alt=\"Clicking Welcome fails\" width=\"800\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_run_click_fails.gif\"><\/p>\n<p>That\u2019s because the browser cannot do module binding. In our case it cannot bind the module from <em>greeting.js<\/em> with the calling module from <em>main.js<\/em>.<\/p>\n<p>This is where the webpack module bundler comes in useful.<\/p>\n<h2 id=\"install_and_configure_webpack\">Install and configure webpack<\/h2>\n<p>Let\u2019s add webpack to our project. To do that, we need to install the <em>webpack<\/em> and <em>webpack-cli<\/em> packages, create a configuration file, and write a script to launch webpack.<\/p>\n<h3 id=\"install_webpack\">Install webpack<\/h3>\n<p>Open the <em>Terminal<\/em> tool window and type:<br \/>\n<code>npm install webpack webpack-cli --save-dev<\/code><br \/>\nThis also adds a <em>package.json<\/em> file to the project.<\/p>\n<h3 id=\"create_a_webpack_configuration_file\">Create a webpack configuration file<\/h3>\n<p>Let\u2019s create <em>webpack.config.js<\/em>. Select the project folder, then go to <em>New | JavaScript File<\/em> from its context menu and specify <em>webpack.config<\/em> as the name of the configuration file. WebStorm will add the <em>.js<\/em> extension automatically.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_new_webpack_config_file.png\" alt=\"Create a Webpack configuration file\" width=\"800\"><\/p>\n<p>Open <em>webpack.config.js <\/em>in the editor and type in the following code:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">module.exports = {\n    entry: &quot;.\/main.js&quot;,\n    output: {\n        path: __dirname + &quot;\/build&quot;,\n        filename: &quot;bundle.js&quot;\n    },\n};<\/pre>\n<p><em>Webpack.config.js<\/em> tells webpack to pack everything that is referenced from <em>main.js<\/em> into one file, <em>bundle.js,<\/em> and store <em>bundle.js<\/em> in a <em>build<\/em> folder under the project root. That\u2019s exactly what we want \u2013 one single file that implements all the application functionality and that can be executed in the browser.<\/p>\n<p>You might be thinking that there\u2019s no <em>build<\/em> folder in our project. Don\u2019t worry, it\u2019ll be created automatically.<\/p>\n<h3 id=\"write_a_script_to_run_webpack\">Write a script to run webpack<\/h3>\n<p>Open <em>package.json<\/em> and add a <code>scripts<\/code> section to it:<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"\">\u201cscripts\u201d: {\n\u201cbuild&quot;: \u201cwebpack&quot;\n}<\/pre>\n<p>This script lets you build and rebuild the application without writing commands in the terminal.<\/p>\n<h2 id=\"build_the_application\">Build the application<\/h2>\n<p>All we need to do now is click the <em>Run Script<\/em> icon in the gutter next to the <a href=\"#write_a_script_to_run_webpack\">script we created<\/a> and select <em>Run \u2018build\u2019<\/em> from the context menu. This will create a <em>build\/bundle.js<\/em> file.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_build_app.png\" alt=\"Run script to build the application\" width=\"800\"><\/p>\n<h2 id=\"run_the_application_second_attempt\">Run the application: second attempt<\/h2>\n<p>We\u2019re almost ready to try re-running our application. However, <em>index.html<\/em> still references <em>main.js.<\/em> We want it to reference <em>bundle.js<\/em> instead, as this is where we have added all the functionality that needs to be executed in the browser. So, let\u2019s replace this:<\/p>\n<p><code>&lt;script src=\"main.js\" type=\"text\/javascript\" &gt;&lt;\/script&gt;<\/code><\/p>\n<p>with this:<\/p>\n<p><code>&lt;script src=\"build\/bundle.js\" type=\"text\/javascript\" &gt;&lt;\/script&gt;<\/code><\/p>\n<p>Open <em>index.html<\/em> and select <em>Run \u2018index.html\u2019<\/em> from its context menu. The browser opens showing the starting page with a <strong>Hello Webpack!<\/strong> message and a <strong>Welcome!<\/strong> button. Let\u2019s click the button and see what happens. The expected greeting message appears!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_run_click_successful.png\" alt=\"Running the application: success\" width=\"800\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_run_click_successful.gif\"><\/p>\n<h3 id=\"automate_the_build_procedure\">Automate the build procedure<\/h3>\n<p>When we ran our application from <em>index.html<\/em>, WebStorm created an <em>index.html<\/em> <a href=\"https:\/\/www.jetbrains.com\/help\/webstorm\/run-debug-configuration.html\" target=\"_blank\" rel=\"noopener\">temporary run configuration<\/a>. Let\u2019s keep this configuration but update it slightly.<\/p>\n<h4 id=\"save_the_temporary_run_configuration\">Save the temporary run configuration<\/h4>\n<p>From the <em>Edit Configuration<\/em> list, select <em>Save \u2018index.html\u2019 Configuration<\/em>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_save_temporary_configuration.png\" alt=\"Save temporary index.html Run\/Debug Configuration\" width=\"800\"><\/p>\n<h4 id=\"add_the_build_script_as_a_before_launch_task\">Add the build script as a <em>Before Launch<\/em> task<\/h4>\n<p>From the <em>Edit Configuration<\/em> list, select <em>Edit Configurations<\/em>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_select_edit_configurations.png\" alt=\"Select Edit Configurations\" width=\"800\"><\/p>\n<p>Now let\u2019s select <em>index.html<\/em> under <em>JavaScript Debug<\/em>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_edit_configurations.png\" alt=\"Edit Configurations dialog: index.html configuration\" width=\"800\"><\/p>\n<p>Then we need to click on the \u201c<em>+<\/em>\u201d icon in the <em>Before launch<\/em> section and choose <em>Run npm script<\/em>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_edit_configuration_add_before_launch_task.png\" alt=\"Add Before Launch task: select Run npm script\" width=\"800\"><\/p>\n<p>In the <em>NPM Script<\/em> dialog, the <em>package.json<\/em> field already shows the path to the project <em>package.json<\/em> where we <a href=\"#write_a_script_to_run_webpack\">defined the build script<\/a>. Select <em>build<\/em> from the <em>Scripts<\/em> list and click <em>OK<\/em>.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_edit_configuration_add_before_launch_task_select_script.png\" alt=\"Add a Before Launch task: select the build script\" width=\"800\"><\/p>\n<p>The build script is now added to the <em>index.html<\/em> run configuration as a <em>Before launch<\/em> task!<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_edit_configuration_before_launch_task_added.png\" alt=\"The build script is added to the index.html Run\/Debug Configuration as a Before Launch task\" width=\"800\"><\/p>\n<h2 id=\"debug_the_application\">Debug the application<\/h2>\n<p>Now let\u2019s debug our application. Our example is quite simple and doesn\u2019t need much debugging, but we\u2019ll use it to illustrate some important steps.<\/p>\n<ol>\n<li>Let\u2019s set a breakpoint on line 2 of the <em>greetings.js<\/em> file so that, when the <strong>Welcome!<\/strong> button is clicked, the application suspends before showing the message.<\/li>\n<\/ol>\n<p>Select the <em>index.html<\/em> configuration from the list and click <em>Debug \u2018index.html\u2019<\/em> or press <em>^D \/ Shift+F9<\/em>. The browser will open showing the home page with a <strong>Hello Webpac!<\/strong> message and a <strong>Welcome!<\/strong> button. The <em>Debug<\/em> tool window will open without frames available.<\/p>\n<ol start=\"2\">\n<li>Let\u2019s click on the <strong>Welcome!<\/strong> button. The <strong>Welcome to WebStorm<\/strong> message appears, and the <em>Debug<\/em> tool window still doesn\u2019t show any frames. It looks like our breakpoint was ignored.<\/li>\n<\/ol>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_debug_index_html_fails.png\" alt=\"Debug the application: the first attempt fails\" width=\"800\" data-gif-src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_debug_index_html_fails.gif\"><\/p>\n<p>This happens because WebStorm cannot match the code that is being executed (the code from the generated <em>bundle.js<\/em> file) to the code that we want to debug (the code in the <em>main.js<\/em> and <em>greeting.js<\/em> files). The good news: Source maps can help us with that.<\/p>\n<h3 id=\"generate_source_maps\">Generate source maps<\/h3>\n<p>Let\u2019s add the following option to the <em>webpack.config.file<\/em>:<br \/>\n<code>devtool: \u201csource-map\u201d<\/code><\/p>\n<p>With this option, webpack will generate source maps that set correspondence between the lines in the <em>main.js<\/em> and <em>greeting.js<\/em> files and the code in the <em>bundle.js<\/em> file, which the browser runs.<\/p>\n<p>To see if it works, let\u2019s run the build script manually. In the <em>package.json<\/em> file, click the <em>Run Script<\/em> gutter icon next to the build script and select <em>Run \u2018build\u2019<\/em> from the context menu. Webpack has generated two files \u2013 <em>bundle.js<\/em> and <em>bundle.js.map<\/em> \u2013 in the <em>build<\/em> folder.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_source_maps_generated.png\" alt=\"Source maps are generated\" width=\"800\"><\/p>\n<p>We won\u2019t need to run the build script manually anymore because WebStorm will execute it automatically as a <a href=\"#add_the_build_script_as_a_before_launch_task\"><em>Before launch<\/em> task<\/a> every time you start the <em>index.html<\/em> run configuration.<\/p>\n<h3 id=\"debug_the_application_with_source_maps\">Debug the application with source maps<\/h3>\n<p>Back to debugging: Select the <em>index.html<\/em> run configuration from the list and click <em>Debug \u2018index.html\u2019<\/em> next to it, or press <em>^D \/ Shift+F9<\/em>. Two things happen:<\/p>\n<ul>\n<li>The browser opens showing the <em>index.html<\/em> page with a <strong>Hello Webpack!<\/strong> message and a <strong>Welcome!<\/strong> button.<\/li>\n<li>The <em>Debug<\/em> tool window opens, but no frames are available.<\/li>\n<\/ul>\n<p>Let\u2019s click on the <strong>Welcome!<\/strong> button. The focus automatically switches to WebStorm, where the <em>Debug<\/em> tool window shows the frames and variables. It lets you step through the code and do everything you usually do while debugging.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/blog.jetbrains.com\/wp-content\/uploads\/2022\/09\/blog_post_webpack_debug_click_successful.png\" alt=\"Debugging session starts successfully\" width=\"800\"><\/p>\n<p>That\u2019s it for this tutorial. If you\u2019re looking for more information on webpack and using it in WebStorm, be sure to check out the <a href=\"https:\/\/www.jetbrains.com\/help\/webstorm\/using-webpack.html#install_and_configure_webpack\" target=\"_blank\" rel=\"noopener\">WebStorm help<\/a>. There are also a lot of <a href=\"https:\/\/webpack.js.org\/\" target=\"_blank\" rel=\"noopener\">great tutorials<\/a> available in the webpack documentation.<\/p>\n<p>Feel free to contact our <a href=\"https:\/\/intellij-support.jetbrains.com\/hc\/en-us\/requests\/new\" target=\"_blank\" rel=\"noopener\">tech support<\/a> if you need help.<\/p>\n<p><em>The WebStorm team<\/em><\/p>\n","protected":false},"author":221,"featured_media":0,"comment_status":"open","ping_status":"open","template":"","categories":[601],"tags":[632,2805],"cross-post-tag":[],"acf":[],"_links":{"self":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/webstorm\/22338"}],"collection":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/webstorm"}],"about":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/types\/webstorm"}],"author":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/users\/221"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/comments?post=22338"}],"version-history":[{"count":9,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/webstorm\/22338\/revisions"}],"predecessor-version":[{"id":284004,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/webstorm\/22338\/revisions\/284004"}],"wp:attachment":[{"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/media?parent=22338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/categories?post=22338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/tags?post=22338"},{"taxonomy":"cross-post-tag","embeddable":true,"href":"https:\/\/blog.jetbrains.com\/zh-hans\/wp-json\/wp\/v2\/cross-post-tag?post=22338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}