I started with WebPack because of the Vue connection, because the scaffolding for Vue was built using WebPack. At the beginning, I thought WebPack was designed for packaging single pages. Later, I thought, Is it too wasteful to use such a good packaging solution only on a single page? If you can use WebPack on traditional multiple pages, would you be more efficient to start with? The good news is that many good front-end developers have written plenty of demos and articles to learn from. I also wrote a small project that I hope will help you learn webpack.

webpack-multi-page

Problems solved by the project

  • SPA is very complicated, I prefer the traditional multi-page application how to break? Or, our project needs back-end rendering, how to produce the page template?
  • Each page of the same UI layout is difficult to maintain, UI slightly changed to each page to change, good trouble is also easy to leak, how to break?
  • Is it possible to integrate ESLint to check syntax?
  • Can postCSS be integrated to enhance browser compatibility?
  • Can I use jquery in Webpack?
  • Can I use typescript in Webpack?

The SRC directory corresponds to the dist directory

When we use Webpack to package multiple pages, we expect SRC directory to be similar to the dist directory after packaging. The development builds the development architecture according to the idea of page modules, and then generates the traditional page architecture after webpack.

/** * const createFiles =function() {
 const usePug = require('.. /config').usePug;
 const useTypeScript = require('.. /config').useTypeScript;
 const path = require('path');
 const glob = require('glob');
 const result = [];
 const type = usePug ? 'pug' : 'html';
 const scriptType = useTypeScript ? 'ts' : 'js'; const files = glob.sync(path.join(__dirname, `.. /src/views/**/*.${type}`));
 for(file of files) { result.push({ name: usePug ? file.match(/\w{0,}(? =\.pug)/)[0] : file.match(/\w{0,}(? =\.html)/)[0], templatePath: file, jsPath: file.replace(type, scriptType),
   stylePath: file.replace(type.'stylus')}); }returnresult; }; // Welcome to join the front-end full stack development exchange circle to learn exchange: 864305860Copy the code

Using this method, we can obtain the file path that needs to be packaged (the module that obtains the file path in this method can also use the FS module). Based on obtaining the packaged file path, we can use the HTML-webpack-plugin to implement multi-page packaging. Since each object instance of the HTmL-webpack-plugin is for/only generates one page, we need to configure multiple object instances of the htML-webpack-plugin for multi-page applications:

const plugins = function() {
 const files = createFiles();
 const HtmlWebpackPlugin = require('html-webpack-plugin');
 const path = require('path');
 const ExtractTextPlugin = require('extract-text-webpack-plugin');
 
 let htmlPlugins = [];
 let Entries = {};
 files.map(file => {
  htmlPlugins.push(
   new HtmlWebpackPlugin({
    filename: `${file.name}.html ', template: file.templatepath, chunks: [file.name]}) Entries[file.name] = file.jspath; // For 1-3 years front-end personnel Entries[file.name] = file.jspath; }); // Help break through technical bottlenecks and improve thinking abilityreturn {
  plugins: [
   ...htmlPlugins,
   new ExtractTextPlugin({
    filename: getPath => {
     return getPath('css/[name].css'); }})], Entries// Welcome to join the front-end full stack development communication circle to learn communication: 864305860}; // For 1-3 years of front-end staff}; // Help break through technical bottlenecks and improve thinking abilityCopy the code

Since I use the ExtractTextPlugin, the CSS code will eventually be generated into a CSS file in the directory of the chunk. Template engine The same UI layout on every page is difficult to maintain, so if the UI is slightly changed, it will be changed on every page. Considering this problem, the project introduced and used puG template engine. Now, we can take advantage of puG features and create a common component: demo.pug p This is a common component and then you can import it when you need to use the common component:

include 'demo.pug'
Copy the code

In addition, you can use all the puG features. Configuring puG in WebPack is also easy, starting with:

npm i --save-dev pug pug-html-loader
Copy the code

Then change all.html suffixes to.pug and use pug syntax. Then add another configuration to the rule

{
  test: /\.pug$/,
  use: 'pug-html-loader'
}
Copy the code

At the same time, change the template in the HtmlWebpackPlugin used in index.html to index.pug.

Webpack integration eslint

Let’s start with the configuration code:

if (useEslint) {
 loaders.push({
  test: /\.js$/,
  loader: 'eslint-loader',
  enforce: 'pre',
  include: [path.resolve(__dirname, 'src')],
  options: {
   formatter: require('stylish')}// Welcome to join the front-end full stack development communication circle, chat learning exchange: 864305860}); // Help break through technical bottlenecks and improve thinking abilityCopy the code

By integrating ESLint with Webpack, we can ensure that compiled code is syntactically error-free and conforms to coding conventions; In development, however, waiting until compile time to notice a problem is probably too slow. So I would suggest that you integrate ESLint into an editor or IDE, like I do with VS Code, and use a plug-in called ESLint that will flag problematic code as soon as it’s written.

Dev environment vs. PROD environment

First, when reading a Webpacl project, you usually start with the package.json file. Because when you type a command on the command line

npm run dev
Copy the code

Webpack will find the Script properties in package.json and analyze the command in turn, so that the command will execute accordingly

nodemon --watch build/ --exec \"cross-env NODE_ENV=development webpack-dev-server --color --progress --config build/webpack.dev.js\"
Copy the code

Similarly, when writing down commands

npm run build
Copy the code

The script will execute

ross-env NODE_ENV=production webpack --config build/webpack.prod.js
Copy the code

This allows you to distinguish between development and production environments. Although we will make a distinction between environments, the project’s configuration common to both environments is consolidated into the (build/webpack.base.js) file based on the principle of non-duplication. The configuration is then pulled together using the Webpack-Merge plug-in

Jquery is used in Webpack

It is also easy to use jquery in Webpack. We can add a configuration to loaders:

if(useJquery) {loaders.push({// pass require('jquery') to introducetest: require.resolve('jquery'), use: [{// welcome to join the front-end full stack development communication loop together to chat learning communication: 864305860 loader:'expose-loader'// The name of the exposed global variable is whatever you want:'jQuery'}, {// same as before:'expose-loader',
    options: '$'}}]); }Copy the code

Then, when you need to use Jq in a js file, reference the exposed variable name:

import $ from 'jQuery';
Copy the code

Typescript is used in Webpack

It is also easy to use jquery in Webpack. We can add a configuration to loaders:

if (useTs) {
 loaders.push({
  test: /\.tsx? $/, use:'ts-loader', exclude: /node_modules/ }); }// Welcome to join the front-end full stack development communication circle to blow water chat learning exchange: 864305860Copy the code

Then change the js file to TS. conclusion

Thank you for watching, if there are shortcomings, welcome to criticize.