webpack 4 :从0配置到项目搭建-程序员宅基地

技术标签: ViewUI  webpack  json  javascript  

本文首发 我的博客
本文涉及到 相关代码

webpack4发布以来,我写项目都是用脚手架,即使再简单的项目,真的是really shame。。虽然道听途说了很多 webpack4 的特性,却没有尝试过,因为它给人的感觉就是,em...很难。但是今天我从最简单的部分开始,一点点搭建起一个项目。

0配置,配置了什么

让我们从0开始,新建一个项目,在终端执行以下语句:

mkdir webpack-4-quickstart && cd webpack-4-quickstart
npm init -y
npm i webpack --save-dev
npm i webpack-cli --save-dev

修改代码 package.jsonscripts 部分:

"scripts": {
  "build": "webpack"
}

现在,我们的 package.json 是这样的:

{
  "name": "webpack-4-quickstart",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
     "build": "webpack"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "webpack": "^4.14.0",
    "webpack-cli": "^3.0.8"
  }
}

此时,我们执行 npm run build, 会给出以下提示/错误:

webpack4-error

  1. error: 没有入口文件
  2. warning: 建议设置 mode 选项

entry & output

为了解决第一个问题,我们尝试新建 src/index.js:

console.log(`I'm a entry point`);

此时再次执行 npm run build,成功打包出了 dist/main.js,因此我们可以得知:

webpack4 more配置了 entry(入口) src/index.js 和output(出口) dist/main.js

当然,如果你想覆盖这个配置(比如修改为 ./foo/src/js/index.js),可以在 package.json 修改:

"scripts": {
  "dev": "webpack --mode development ./foo/src/js/index.js --output ./foo/main.js",
  "build": "webpack --mode production ./foo/src/js/index.js --output ./foo/main.js"
}

production & development

webpack4 之前,我们写一个项目起码会设置两种类型文件:

  • 用于开发环境的webpack.dev.conf.js,定义 webpack 启动的服务器等
  • 用于生产环境的webpack.prod.conf.js,定义UglifyJSPlugin或其他配置等

而 webpack4 的 mode 给出了两种配置:developmentproduction

我们修改 package.jsonscripts 部分:

"scripts": {
  "dev": "webpack --mode development",
  "build": "webpack --mode production"
}

我们分别执行 npm run devnpm run build

webpack4-mode

执行 npm run dev 打包的是未压缩的代码,而 npm run build 是压缩后的代码。

  • 生产模式下:启用了 代码压缩、作用域提升(scope hoisting)、 tree-shaking,使代码最精简
  • 开发模式下:相较于更小体积的代码,提供的是打包速度上的优化

总结

webpack 4 的零配置主要应用于:

  • entry 默认设置为 ./src/index.js
  • output 默认设置为 ./dist/main.js
  • productiondevelopment 两种模式

项目搭建

项目搭建,我们对webpack的诉求是:

  • js的处理:转换 ES6 代码,解决浏览器兼容问题
  • css的处理:编译css,自动添加前缀,抽取css到独立文件
  • html的处理:复制并压缩html文件
  • dist的清理:打包前清理源目录文件
  • assets的处理:静态资源处理
  • server的启用:development 模式下启动服务器并实时刷新

转换 ES6 代码,解决浏览器兼容问题

用 babel 转换 ES6 代码

用 babel 转换 ES6 代码需要使用到 babel-loader ,我们需要安装一系列的依赖:

    npm i babel-core babel-loader babel-preset-env --save-dev

然后在根目录新建一个babel配置文件 .babelrc

    {
        "presets": [
            "env"
        ]
    }

那么如何将配置用于webpack打包中?

  • 新建一个 webpack 的配置文件
  • 在 npm scripts 中使用 --module-bind
  1. 使用 webpack 的配置文件的方法:

    新建 webpack.config.js

        module.exports = {
          module: {
            rules: [
              {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                  loader: "babel-loader"
                }
              }
            ]
          }
        }
  2. 在 npm scripts 中配置的方法:
    "scripts": {
      "dev": "webpack --mode development --module-bind js=babel-loader",
      "build": "webpack --mode production --module-bind js=babel-loader"
    }
使用 babel-polyfill 解决兼容性问题

然而浏览器依然不支持一些语法的使用,导致兼容性问题,我们用 babel-polyfill 解决:

    npm i babel-polyfill babel-plugin-transform-runtime  --save-dev

.babelrc 添加配置:

{
    "presets": [
        "env"
    ],
    "plugins": [
       "transform-runtime"
    ]
}

最后在 webpack.config.js 中将 babel-polyfill 加到你的 entry 数组中:

const path = require('path');
module.exports = {
    entry: [
        "babel-polyfill",
        path.join(__dirname, './src/index.js')
    ],
    // ...
};

编译css,自动添加前缀,抽取css到独立文件

webpack 并不会主动将你的css代码提取到一个文件,过去我们使用 extract-text-webpack-plugin,在webpack4中我们使用mini-css-extract-plugin来解决这个问题。

postcss-loader 用于添加浏览器前缀,相关配置我喜欢在根目录新建 postcss.config.js 配置

    npm i mini-css-extract-plugin css-loader --save-dev
    npm i style-loader postcss-loader  --save-dev
    // webpack.config.js
    const MiniCssExtractPlugin = require("mini-css-extract-plugin");
    module.exports = (env, argv) => {
      const devMode = argv.mode !== 'production'
      return {
        module: {
          rules: [
            // ...,
            {
                test: /\.css$/,
                use: [
                    devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                    'css-loader',
                    'postcss-loader'
                ]
            },
            ]
          },
          plugins: [
            // ...,
            new MiniCssExtractPlugin({
              filename: "[name].css",
              chunkFilename: "[id].css"
            })
          ]
      }
    }
// postcss.config.js
    module.exports = {
        plugins: {
            autoprefixer: {}
        }
    }

复制并压缩html文件 html-webpack-plugin

    npm i html-webpack-plugin html-loader --save-dev
    // webpack.config.js
    const HtmlWebPackPlugin = require("html-webpack-plugin");
    module.exports = {
        module: {
            rules: [
                // ...,
                {
                    test: /\.html$/,
                    use: [{
                        loader: "html-loader",
                        options: {
                            minimize: true
                        }
                    }]
                }
            ]
        },
        plugins: [
            new HtmlWebPackPlugin({
                template: "./src/index.html",
                filename: "./index.html"
            })
        ]
    };

打包前清理源目录文件 clean-webpack-plugin

每次打包,都会生成项目的静态资源,随着某些文件的增删,我们的 dist 目录下可能产生一些不再使用的静态资源,webpack并不会自动判断哪些是需要的资源,为了不让这些旧文件也部署到生产环境上占用空间,所以在 webpack 打包前最好能清理 dist 目录。

    npm install clean-webpack-plugin --save-dev
  const CleanWebpackPlugin = require('clean-webpack-plugin');
  module.exports = {
    plugins: [
      new CleanWebpackPlugin(['dist']),
    ]
  };

静态资源处理 file-loader

    npm install file-loader --save-dev
    // webpack.config.js
    module.exports = {
      module: {
        rules: [
          {
            test: /\.(png|jpg|gif)$/,
            use: [
              {
                loader: 'file-loader',
                options: {}
              }
            ]
          }
        ]
      }
    }

development 模式下启动服务器并实时刷新 webpack-dev-server

    npm i webpack-dev-server --save-dev

package.json

    "scripts": {
      "start": "webpack-dev-server --mode development --open",
      "build": "webpack --mode production"
    }

使用 webpack 4 建立 react 项目

现在我们模仿 create-react-app 的结构,自己搭建一个 react 项目,并且用less预编译:

  ├── public
  │   └── index.html      # html 模板
  ├── src
  │   ├── assets          # 静态资源
  │   │   └── logo.png
  │   ├── components      # 组件
  │   │   └── App.js
  │   ├── index.js        # 入口文件
  │   └── styles
  │       └── index.less
  ├── .babelrc
  ├── package-lock.json
  ├── package.json
  ├── postcss.config.js
  └── webpack.config.js

在以上的基础(项目搭建部分),再安装react相关模块及less模块:

    npm i react react-dom --save
    npm i babel-preset-react --save-dev
    npm i less less-loader --save-dev

修改 .babelrc:

    {
      "presets": ["env", "react"]
    }

修改 webpack.config.js

    // webpack.config.js
    const path = require('path');
    module.exports = (env, argv) => {
        const devMode = argv.mode !== 'production'
        return {
            entry: [
                "babel-polyfill",
                path.join(__dirname, './src/index.js')
            ],
            devServer: {
                port: 3000, //端口号
            },
            module: {
                rules: [
                    // ...
                    // 处理react
                    {
                        test: /\.(js|jsx)$/,
                        exclude: /node_modules/,
                        use: {
                            loader: "babel-loader"
                        }
                    },
                    // 处理less
                    {
                        test: /\.less$/,
                        use: [
                            devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                            'css-loader',
                            'postcss-loader',
                            'less-loader',
                        ]
                    }
                ]
            }
        }
    };

基本上搭建完这个项目了,如果你想看完整代码

使用 webpack 4 建立 vue 项目

同样地,我们模仿 vue-cli 的结构,自己搭建一个 vue 项目,这次我们的css预编译语言用 scss

  ├── public
  │   └── index.html      # html 模板
  ├── src
  │   ├── assets          # 静态资源
  │   │   └── logo.png
  │   ├── components      # 组件
  │   │   └── App.vue
  │   ├── main.js        # 入口文件
  │   ├── main.js        # 入口文件
  │   └── styles
  │       └── index.scss
  ├── .babelrc
  ├── package-lock.json
  ├── package.json
  ├── postcss.config.js
  └── webpack.config.js

在以上的基础(项目搭建部分),再安装vue相关模块及sass模块:

    npm i vue --save
    npm i vue-loader vue-template-compiler --save-dev
    npm i node-sass sass-loader --save-dev
    // webpack.config.js
    const path = require('path');
    const VueLoaderPlugin = require('vue-loader/lib/plugin')

    module.exports = (env, argv) => {
        const devMode = argv.mode !== 'production'
        return {
            entry: [
                "babel-polyfill",
                path.join(__dirname, './src/main.js')
            ],
            module: {
                rules: [
                    // ...
                    // 解析vue
                    {
                        test: /\.vue$/,
                        loader: 'vue-loader',
                        options: {
                            loaders: {}
                        }
                    },
                    // 处理scss
                    {
                        test: /\.scss$/,
                        use: [
                            devMode ? 'style-loader' : MiniCssExtractPlugin.loader,
                            'css-loader',
                            'postcss-loader',
                            'sass-loader',
                        ]
                    }
                ]
            },
            plugins: [
                // ...
                new VueLoaderPlugin()
            ]
        }
    };

一个简易的 vue-cli 也搭建完成,如果你想看完整代码

参考资源

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_34129696/article/details/88794531

智能推荐

js-选项卡原理_选项卡js原理-程序员宅基地

文章浏览阅读90次。【代码】js-选项卡原理。_选项卡js原理

设计模式-原型模式(Prototype)-程序员宅基地

文章浏览阅读67次。原型模式是一种对象创建型模式,它采用复制原型对象的方法来创建对象的实例。它创建的实例,具有与原型一样的数据结构和值分为深度克隆和浅度克隆。浅度克隆:克隆对象的值类型(基本数据类型),克隆引用类型的地址;深度克隆:克隆对象的值类型,引用类型的对象也复制一份副本。UML图:具体代码:浅度复制:import java.util.List;/*..._prototype 设计模式

个性化政府云的探索-程序员宅基地

文章浏览阅读59次。入选国内首批云计算服务创新发展试点城市的北京、上海、深圳、杭州和无锡起到了很好的示范作用,不仅促进了当地产业的升级换代,而且为国内其他城市发展云计算产业提供了很好的借鉴。据了解,目前国内至少有20个城市确定将云计算作为重点发展的产业。这势必会形成新一轮的云计算基础设施建设的**。由于云计算基础设施建设具有投资规模大,运维成本高,投资回收周期长,地域辐射性强等诸多特点,各地在建...

STM32问题集之BOOT0和BOOT1的作用_stm32boot0和boot1作用-程序员宅基地

文章浏览阅读9.4k次,点赞2次,收藏20次。一、功能及目的 在每个STM32的芯片上都有两个管脚BOOT0和BOOT1,这两个管脚在芯片复位时的电平状态决定了芯片复位后从哪个区域开始执行程序。BOOT1=x BOOT0=0 // 从用户闪存启动,这是正常的工作模式。BOOT1=0 BOOT0=1 // 从系统存储器启动,这种模式启动的程序_stm32boot0和boot1作用

C语言函数递归调用-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏22次。C语言函数递归调用_c语言函数递归调用

明日方舟抽卡模拟器wiki_明日方舟bilibili服-明日方舟bilibili服下载-程序员宅基地

文章浏览阅读410次。明日方舟bilibili服是一款天灾驾到战斗热血的创新二次元废土风塔防手游,精妙的二次元纸片人设计,为宅友们源源不断更新超多的纸片人老婆老公们,玩家将扮演废土正义一方“罗德岛”中的指挥官,与你身边的感染者们并肩作战。与同类塔防手游与众不同的几点,首先你可以在这抽卡轻松获得稀有,同时也可以在战斗体系和敌军走位机制看到不同。明日方舟bilibili服设定:1、起因不明并四处肆虐的天灾,席卷过的土地上出..._明日方舟抽卡模拟器

随便推点

Maven上传Jar到私服报错:ReasonPhrase: Repository version policy: SNAPSHOT does not allow version: xxx_repository version policy snapshot does not all-程序员宅基地

文章浏览阅读437次。Maven上传Jar到私服报错:ReasonPhrase: Repository version policy: SNAPSHOT does not allow version: xxx_repository version policy snapshot does not all

斐波那契数列、素数、质数和猴子吃桃问题_斐波那契日-程序员宅基地

文章浏览阅读1.2k次。斐波那契数列(Fibonacci Sequence)是由如下形式的一系列数字组成的:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, …上述数字序列中反映出来的规律,就是下一个数字是该数字前面两个紧邻数字的和,具体如下所示:示例:比如上述斐波那契数列中的最后两个数,可以推导出34后面的数为21+34=55下面是一个更长一些的斐波那契数列:0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610, 987, 1597, 2584,_斐波那契日

PHP必会面试题_//该层循环用来控制每轮 冒出一个数 需要比较的次数-程序员宅基地

文章浏览阅读363次。PHP必会面试题1. 基础篇1. 用 PHP 打印出前一天的时间格式是 2017-12-28 22:21:21? //>>1.当前时间减去一天的时间,然后再格式化echo date('Y-m-d H:i:s',time()-3600*24);//>>2.使用strtotime,可以将任何字符串时间转换成时间戳,仅针对英文echo date('Y-m-d H:i:s',str..._//该层循环用来控制每轮 冒出一个数 需要比较的次数

windows用mingw(g++)编译opencv,opencv_contrib,并install安装_opencv mingw contrib-程序员宅基地

文章浏览阅读1.3k次,点赞26次,收藏26次。windows下用mingw编译opencv貌似不支持cuda,选cuda会报错,我无法解决,所以没选cuda,下面两种编译方式支持。打开cmake gui程序,在下面两个框中分别输入opencv的源文件和编译目录,build-mingw为你创建的目录,可自定义命名。1、如果已经安装Qt,则Qt自带mingw编译器,从Qt安装目录找到编译器所在目录即可。1、如果已经安装Qt,则Qt自带cmake,从Qt安装目录找到cmake所在目录即可。2、若未安装Qt,则安装Mingw即可,参考我的另外一篇文章。_opencv mingw contrib

5个高质量简历模板网站,免费、免费、免费_hoso模板官网-程序员宅基地

文章浏览阅读10w+次,点赞42次,收藏309次。今天给大家推荐5个好用且免费的简历模板网站,简洁美观,非常值得收藏!1、菜鸟图库https://www.sucai999.com/search/word/0_242_0.html?v=NTYxMjky网站主要以设计类素材为主,办公类素材也很多,简历模板大部个偏简约风,各种版式都有,而且经常会更新。最重要的是全部都能免费下载。2、个人简历网https://www.gerenjianli.com/moban/这是一个专门提供简历模板的网站,里面有超多模板个类,找起来非常方便,风格也很多样,无须注册就能免费下载,_hoso模板官网

通过 TikTok 联盟提高销售额的 6 个步骤_tiktok联盟-程序员宅基地

文章浏览阅读142次。你听说过吗?该计划可让您以推广您的产品并在成功销售时支付佣金。它提供了新的营销渠道,使您的产品呈现在更广泛的受众面前并提高品牌知名度。此外,TikTok Shop联盟可以是一种经济高效的产品或服务营销方式。您只需在有人购买时付费,因此不存在在无效广告上浪费金钱的风险。这些诱人的好处是否足以让您想要开始您的TikTok Shop联盟活动?如果是这样,本指南适合您。_tiktok联盟