From Gulp to Webpack
Gulp vs Webpack
In my project I have migrated from Gulp to Webpack. The project has these technologies:
backend: Express.js
frontend: React/Redux, Stylus.
Today the project is not complete. I have worked with Gulp, but now I turned to Webpack. What is difference between Gulp and Webpack?
Gulp is a task runner, Webpack — module bundler. Gulp lets automate repeatable activities. It merges files, compiles Stylus, minifies CSS, uglifies JS. It is simple tool, I liked it, because is very easy to learn.
Modules which I used in gulpfile.js:
When I read about Webpack, I understood, that Webpack isn’t a task runner. Webpack works with complex depedency resolution. Webpack reads js code and recursively process module imports in code. Only Webpack understands dependency logic. If you work with plain Javascript functions, without modules, Webpack doesn’t have advantages, but if you develop with Js libraries, frameworks, like React — Webpack is the best choice. For React I think Webpack is the best choice. Only Webpack can understand vendor and app code and can create bundles without manual configuration.
But Webpack for CSS is not a very suitable choice. Some developers uses Webpack and Gulp together. Webpack made for Javascript firstly. It generates static assets from modules and dependencies. Webpack has a hot module replacement tool, which can replace modules in production mode.
Webpack for beginners is not simple tool and it documentation is horrible. But litle by litle and we have new project. Webpack 4 version has some changes, therefore a some code from Internet cannot work, because it made for Webpack earlier versions.
My project structure
Webpack recommends in a project create src and dist folders. Src for Javascript, CSS source files and dist compiled bundles. But I think it is good only for small projects, but for big projects needs something else. If in your project folder is backend and frontend together, than src folder name is confusing. Because src can be for PHP code, Laravel, Javascript, html templates, css and etc. I like Laravel recomended folder structure, and I use it in non Laravel projects.
Expressjs project structure
my_project
--app // mvc for Expressjs backend
----controllers
----facades
----services
----models // MySQL entities
----views //handlebar templates
--config
--public // like dist in Webpack recommendations
----js
----css
----img
--resources // like src in Webpack
----assets
------js
--------source // React.js
------stylus // css preprocessor
----locales //i18 languages for templates
------enWebpack sends compiled files from resources to public folder. Nginx from public folder sends files to browsers.
Stylus source
Stylus has this structure:
components
helpers
layouts
modules
partials
pages
base.stylbase.styl file imports all these files.
React/Redux source
React has this structure:
actions
components
constants
containers
helpers
reducers
store
home-index.jsxhome-index.jsx is the main file for creating bundle.
Package.json for Webpack
We can start webpack from console with command: webpack. But it is better to configure into package.json with some keys.
So…
Get Audrus’s stories in your inbox
Join Medium for free to get updates from this writer.
Webpack starts in developing mode.
npm run devWebpack starts in production mode.
npm run buildWith cross-env I send a NODE_ENV variable to webpack.config.js file.
Webpack configuration
Webpack 4 version can work without webpack.config.js file. But if need for you advanced settings, you have to create webpack.config.js file into your project folder.
I want to get separate vendor and app files.
app-home.js // my app
app-signup.js // my other app
vendor.js //React, Redux and other librariesMy webpack.config.js file modules.
Some stuff…
Function resolve creates full path. Array bablePlugins in production mode add transform-react-remove-prop-types which remove propTypes from React code. Why? Because React doesn’t use propTypes in production mode and we can optimize a bundle size.
I enabled source map, because I wanted to create two different React app bundles and one a css bundle. I disabled hints, because Webpack show warnings if asset created is over 250kb. The entry parameter has ‘js/app-home’ path because without ‘js/’ preffix .js and .css files will be send to /public. With this configuration .js files will be send to /public/js.
There is output for the js bundles. The chunkFilename parameter is for vendor file. Webpack has great feature — it collects all imports from node_modules and make vendor.js file. The name parameter is for my apps. The path parameter is /public.
The minimize parameter is false, because when it was true it conflicted with Uglifyjs. The concatenateModules is enabled in production mode by default. There a two cacheGroups: default for app bundles and vendor for vendor bundle. Webpack in vendor bundle will send all modules from my app files what are imported from node_modules.
Firstly runs eslint-loader. It has .eslintrc.json config file.
I tried to extend with airbnb but it show a lot of errors in my apps. For example airbnb show error in Popup.jsx file at 30 row. But Popup.jsx has only 5 rows. I have searched in Internet but I can’t get true answer. So, I turned to “eslint:recommended”, “plugin:react/recommended”. If you have answer for airbnb — I will glad to get comment.
Babel-loader will reformat code for last 4 browsers versions by caniuse.com.
Resolve is important for js and styl files.
There is plugins. CopyWebpackPlugin copy from node_modules normalize.css file to resource. The node_modules is reserverd for vendor files and it is denied for get normalize.css. Without MiniCssExtractPlugin we can’t create css bundle.
Conclusion
In develop mode I got vendor.js 1,5 MB, in production mode — 240 KB. app-home.js in develop — 86 KB, in production — 23 KB.
In future webpack.config.js file I can improve, but today it works without problems.









