Build a project based webpack4 from a negative start

Foreword

Copy and paste as a engineer, has always been (probably only me o (╥﹏╥) o)

vue create hello-world
npx create-react-app hello-world
复制代码

Order a meal like this scaffolding operation, what Babel ah, Postcss, all kinds of Loader, Eslint ah Uglifyjs have a shuttle Well, then goose in the end is how these configurations, the time does not meet the requirements of how to do it? These scaffolds are based Webpack (What Webpack that? Point I ), and recently wrote a native JS project, no scaffolding is no Babel, autoprefixer, Uglifyjs, then who gave me turn the code, who gave me add browser prefixes, who gave me the code compression ah! Copy and paste self-cultivation engineer told I can not do that live or let someone else doing betterヽ(✿゚▽゚) Techno

So we started a new copy tour

Start

Copy a first-come, new projects, the project root directory npm init -y, -y is the whole yes, as to what yes the chest brother who can not -y try ︿ (¯)¯) ︿

More than a package.json the project directory, which records the information related to the project.

Based Webpack course we want to install a Webpack

npm i webpack webpack-cli -D
复制代码

After the command is completed, the project more than a node_modules folder, the folder is used to store programs installed dependencies, subsequent packets will also project dependencies inside.

Initialize the project directory, create src, dist, config and index.html (html casually write Diansha such as hello world and so will open at least not white line), as well as files in the src directory entry index.js (ie empty can)

The basic initialization is complete webpack packaged default entry to src / index.js, the default mode is packaged --mode development, packaging, there are two modes in total:

  • mode development (development environment)
  • mode production (production)

You can now package.json -> scripts section configured build command

{
  "name": "test-webpack-bundler",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack --mode production"
  },
  下面太长省略了...
}
复制代码

Then executenpm run build

Look has packed a success! Long only just begun ...

webpack configuration engineer warning (1 • ㅂ •) و✧

Disposing webpack trip

Development environment

First npm i webpack-dev-server html-webpack-plugin internal-ip -Ddevelopment environment for local services rely webpack-dev-server , and generate html, js, etc. will be automatically inserted by html-webpack-plugin , and LAN equipment can rely on IP access by internal-ip create a new directory in the config webpack.dev .js

Time again to copy and paste it

const path = require("path");
const webpack = require("webpack");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const packageConfig = require("../package.json");
const internalIp = require('internal-ip') // 借助这个实现可用局域网IP访问

const devWebpackConfig = {
  mode: "development",
  devtool:'#source-map',
  devServer: {
    port: 9527, // 指定端口号; 默认 8080
    hot: true, // 热更新
    host: internalIp.v4.sync(), // 可通过局域网IP访问,也可以通过 localhost 访问
    open: true, // 启动本地服务后,自动打开页面
    overlay: true, // 编译器错误或警告时, 在浏览器中显示全屏覆盖; 默认false
    progress: true, // 是否将运行进度输出到控制台; 默认 false
    contentBase: path.resolve(__dirname, "dist"), // 告诉服务器从哪里提供内容。只有在你想要提供静态文件时才需要
    publicPath: "/",
    // 精简终端输出
    stats: {
      modules: false,
      children: false,
      chunks: false,
      chunkModules: false
    }
  },
  entry: ["./src/index.js"],
  plugins: [
    new HtmlWebpackPlugin({
      template: "index.html", // 指定模板html文件
      title: packageConfig.name, // html的title的值,这里我从package.json里取了
      inject: true, // 自动引入JS脚本的位置,默认值为 true
    })
  ]
};

module.exports = devWebpackConfig;

复制代码

devtool details see here now package.json - command to configure the dev> scripts in

"dev": "webpack-dev-server --config config/webpack.dev.js --color --progress"
复制代码

Now npm run dev, right chest brother who is familiar with do not do it, you go


No problem we continue to have problems ??? chest brother who Baidu about it

Now we've put together a directory on the project reference Vue Cli generated it

  • assets primarily icon picture ah ah ah like font
  • styles that it css
  • utils that the utility functions such as writing (copying) of a stabilization ah, ah throttle, thrown into the time format to ah like, can be introduced with the time

webpack only know js, icons, fonts, css and other various loader would need to show it webpack, it was recognized.

Css first get it, the way to sass and scss also engage (less the same token, you can find the corresponding loader) just write a few words about the meaning

index.html

    <header class="flex-container header-wrapper">
      <h1 class="title">test-webpack4-bundler</h1>
      <div class="user-avatar-box">
        <img class="adaptive-img" src="./src/assets/uncle.jpg" alt="" />
      </div>
      <ul>
        <li class="list-item">1</li>
        <li class="list-item">2</li>
        <li class="list-item">3</li>
        <li class="list-item">4</li>
        <li class="list-item">5</li>
        <li class="list-item">6</li>
      </ul>
    </header>
复制代码

src/index.js

import './styles/index.scss' // global css

复制代码

src/styles/index.scss

@import "./header.scss";

.flex-container {
  display: flex;
  justify-content: center;
  align-items: center;
}

.adaptive-img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: center;
}

复制代码

src/styles/header.scss

.header-wrapper {
  flex-direction: column;
  .title {
    color: rgb(65, 85, 28);
  }
  .user-avatar-box {
    width: 120px;
    height: 120px;
    overflow: hidden;
    border-radius: 50%;
  }
}
复制代码

copy and paste

npm i css-loader style-loader sass-loader sass postcss-loader autoprefixer -D
复制代码

Look loaded a bunch of name also know about doing it postcss-loader with autoprefixer can automatically add these prefixes the -webkit

(Of course PostCSS also capable lot of things, if you want to understand the point I )

config / webpack.dev.js years, and plugins peer configuration loader

  module: {
    rules: [
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          "style-loader",
          "css-loader",
          "postcss-loader",
          {
            loader: "sass-loader",
            options: {
              implementation: require("sass")
              // 默认使用的node-sass,这样配置就会使用dart-sass
            }
          }
          // webpack的规定,多个loader要倒着写,比如scss文件先给sass-loader解析成css再给css-loader,以此类推
        ]
      }
    ]
  }
复制代码

It creates two files in the root directory of the project to configure postcss-loader and autoprefixer

.browserslistrc

> 1%
last 2 versions
not ie <= 9

复制代码

postcss.config.js

module.exports = {
  plugins: {
    autoprefixer: {}
  }
};

复制代码

You can npm run devalready see the way we want and have automatic prefix for different kernel


css part is over, now we regressed to write code for it

utils/index.js

export function $(selector) {
  return document.querySelector(selector);
}

复制代码

src/index.js

import "./styles/index.scss"; // global css
import { $ } from "./utils";
import { resolve } from "path";

window.onload = () => {
  const showText = "守护姨父的微笑";
  setTimeout(() => {

  }, 1000);
  const changeTitle = () => {
    let myPromise = new Promise((resolve, reject) => {
      resolve();
    });
    return myPromise;
  };
  changeTitle().then(()=>{
    $(".title").innerHTML = `我们要${showText}`;
    const lists = [...document.querySelectorAll(".list-item")];
    lists.forEach(element => {
      console.log(element);
    });
    let [a, b, c] = ["索尼好!退果报平安", 2, 3];
    console.log(a);
    $(".title").innerHTML = `我们要${showText}${a}`;
  })
};

复制代码

Well, we wrote arrow function template string, const statement, Promise is es6 syntax, not some modern browsers do not support, so we need to help our brother Babel

copy and paste

npm i babel-loader @babel/core @babel/preset-env @babel/runtime @babel/plugin-transform-runtime @babel/plugin-syntax-dynamic-import -D
复制代码

src / index.js introducing head gasket

import "@babel/polyfill";
复制代码

New .babelrc project root directory

{
  "presets": ["@babel/preset-env"],
  "plugins": [
    "@babel/plugin-transform-runtime"
  ]
}

复制代码

config / webpack.dev.js in module> rules to increase at a loader

      {
        test: /\.js$/,
        use: ["babel-loader"],
        exclude: /node_modules/
      },
复制代码

config/webpack.dev.js entry加入 @babel/polyfill

entry: ["@babel/polyfill","./src/index.js"]
复制代码

package.json -> scripts build

"build": "webpack --config config/webpack.dev.js --mode production --color --progress"
复制代码

npm run buildWave away

es6 grammar are gone, the others also have gasket

(babel-polyfill and relationships and differences babel-runtime can probably see here )

Like probably get that done? Etc., packing out html file reference picture seems wrong path, no hash value iteration cache may not Gaosi us ah, then copy and paste the next round started again.


Production Environment

It's that kind of development environment is probably right, for a production environment we need to do something the first copy webpack.dev.js, called webpack.prod.js, as webpack production environment configuration

Equipment, are solved in html and js file path issue

npm i url-loader file-loader html-withimg-loader -D
复制代码

Then remove the development server,

config/webpack.prod.js

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const packageConfig = require("../package.json");

const prodWebpackConfig = {
  mode: "production",
  devtool: false,
  entry: ["@babel/polyfill", "./src/index.js"],
  output: {
    path: path.resolve(__dirname, "../dist"),
    filename: path.posix.join("static", "js/[name].[chunkhash].js"),
    chunkFilename: path.posix.join("static", "js/[id].[chunkhash].js")
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        use: ["babel-loader"],
        exclude: /node_modules/
      },
      {
        test: /\.(sa|sc|c)ss$/,
        use: [
          "style-loader",
          "css-loader",
          "postcss-loader",
          {
            loader: "sass-loader",
            options: {
              implementation: require("sass")
              // 默认使用的node-sass,这样配置就会使用dart-sass
            }
          }
          // webpack的规定,多个loader要倒着写,比如scss文件先给sass-loader解析成css再给css-loader,以此类推
        ]
      },
      {
        test: /\.(htm|html)$/,
        loader: "html-withimg-loader"
      },
      {
        test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
        loader: "url-loader",
        options: {
          limit: 10000,
          name: path.posix.join("static", "img/[name].[hash:7].[ext]")
        }
      },
      {
        test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
        loader: "url-loader",
        options: {
          limit: 10000,
          name: path.posix.join("static", "fonts/[name].[hash:7].[ext]")
        }
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: "index.html", // 指定模板html文件
      title: packageConfig.name, // html的title的值,这里我从package.json里取了
      inject: true, // 自动引入JS脚本的位置,默认值为 true
      minify: {
        minifycss: true, // 压缩css
        minifyJS: true, // 压缩JS
        removeComments: true, // 去掉注释
        collapseWhitespace: true, // 去掉空行
        removeRedundantAttributes: true, // 去掉多余的属性
        removeAttributeQuotes:true, // 删除不需要引号的属性值
        removeEmptyAttributes: true // 去掉空属性
      }
    })
  ]
};

module.exports = prodWebpackConfig;

复制代码

package.json -> scripts build with the configuration of the production environment build

"build": "webpack --config config/webpack.prod.js --mode production --color --progress"
复制代码

npm run buildWave away

You can see, html compression over, img path is also correct, and the directory structure while also more neat, files with the hash value

end

Substantially completed, follow-up and some optimization, such as plug-ins to use the specified compression JS, CSS pulled into a single file and optimize the static resource static copy in the root directory to the directory and other packaged separately detached third party libraries, not one to say, mainly to write this stuff too tired. . . Bigwigs good Niubi. . . . Really

If there is where the problem is welcome bigwigs tell me! thanksgiving!

Attach this project address which contains a more complete configuration, at least in my project probably is the case.

Reproduced in: https: //juejin.im/post/5cfa26fbf265da1b8e709116

Guess you like

Origin blog.csdn.net/weixin_33785972/article/details/91462759