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

智能推荐

页面打印-程序员宅基地

文章浏览阅读92次。最佳答案对JS的打印方法总结一下,方便日后查阅。一.用JS自带函数打印直接调用Java代码 复制代码 1. <a href="javascript:window.print();">打印</a> <a href="javascript:window.print();">打印</a>..._toolbar: true可以打印页面吗

中国操作系统变迁史,鸿蒙之前的尸骨_国产操作系统的崛起之路的相关介绍-程序员宅基地

文章浏览阅读1.3w次,点赞156次,收藏236次。本文转载自程序员极客实验室把时钟调回到16年前,地处北京市东部远郊的平谷区做了一个大胆的决定:在全区行政公务系统全部大范围地使用国产Linux桌面操作系统,并纳入考核。此行的目的,是展开全面取代微软Windows的尝试。然而,国产操作系统并不受欢迎。在一年多的推广过程中,大家像小孩子过家家一样,在检查时用国产,检查完换盗版微软。许多问题暴露出来。比如,本来在使用微软浏览器上网很正常实现的功能,Linux下的浏览器却不能正常使用。16年过去了,6月2日晚间,华为在直播中,向观..._国产操作系统的崛起之路的相关介绍

char格式化linux和windows区别_linux和windows char区别-程序员宅基地

文章浏览阅读980次。在windows下可以使用 ''%C",将char字符格式化输入成大写字母而linux只能使用 "%c"进行格式化输入_linux和windows char区别

PAT-A-1006 Sign In and Sign Out【简单模拟】-程序员宅基地

文章浏览阅读3.8w次。At the beginning of every day, the first person who signs in the computer room will unlock the door, and the last one who signs out will lock the door. Given the records of signing in's and out's, you...

TFTP传输---wireshark抓包工具,听诊器_tftp抓包-程序员宅基地

文章浏览阅读1.9k次,点赞2次,收藏6次。1.广播受限广播2.每两个16位进制组成一个字节,再翻译成ASCII码_tftp抓包

2021年双十一活动,淘宝/天猫喵糖/京东双11任务自动助手软件+淘宝/京东/拼多多/抖音/直播抢购软件,分享代码_天猫双11幻想岛辅助-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏26次。软件下载地址https://www.lanzoui.com/b01cfbrbihttps://www.lanzoui.com/b01cfbrbi功能1、支持天猫喵糖/京东双11任务自动完成,领取奖励(亲测可能,部分任务需要手动)2、支持淘宝/天猫/京东/拼多多/抖音/直播抢购,支持BP模式(测试了京东可以自动下单)if (!auto.service) { toast('无障碍服务未启动!退出!') exit()} // 打开淘宝活动页面 .._天猫双11幻想岛辅助

随便推点

修改Cisco交换机ntp服务器,在无线局域网控制器配置示例的NTP-程序员宅基地

文章浏览阅读859次。Introduction本文解释如何配置无线局域网控制器(WLCs)同步的日期和时间与网络时间协议(NTP)服务器。PrerequisitesRequirements尝试进行此配置之前,请确保满足以下要求:Cisco WLCs的配置的基础知识。NTP基础知识。Components Used本文档中的信息基于以下软件和硬件版本:CiscoWLC运行软件版本8.8.110.0的3504。运行Cisc..._cisco 3560 ntp

pandas合并多个DataFrame_pd.merge多个dataframe-程序员宅基地

文章浏览阅读7.1k次,点赞5次,收藏16次。pandas合并多个DataFrame合并两个DataFrame合并多个DataFrame合并两个DataFrame合并两个DataFrame用pd.mergeimport pandas as pdimport numpy as npdf1 = pd.DataFrame(np.array([ ['a', 1, 2], ['b', 3, 4], ['c', 5, 6]]), columns=['name', 'num11', 'num12'])df2 = pd._pd.merge多个dataframe

ArrayList核心代码注释汉化-程序员宅基地

文章浏览阅读244次。public class ArrayList<E> extends AbstractList<E> implements List<E>, RandomAccess, Cloneable, java.io.Serializable { private sta..._arraylist代码注释汉化

软件测试面试题:怎么设计接口测试用例?_面试题如何设计接口-程序员宅基地

文章浏览阅读2.3k次,点赞5次,收藏27次。怎么设计接口测试用例?通常,设计接口测试用例需要考虑以下几个方面:(1)是否满足前提条件有些接口需要满足前提,才可成功获取数据。常见的,需要登录Token逆向用例:针对是否满足前置条件(假设为n个条件),设计0~n条用例(2)是否携带默认值参数正向用例:带默认值的参数都不填写、不传参,必填参数都填写正确且存在的“常规”值,其他不填写,设计1条用例(3)业务规则、功能需求这里根据时间情况,结合接口参数说明,可能需要设计N条正向用例和逆向用例..._面试题如何设计接口

jQuery实现遮蔽层的弹出层,根据后台循环取出的数据弹出所要的DIV层_jquery 弹出层后端获取-程序员宅基地

文章浏览阅读340次。<style type="text/css"> .bgDiv{ background-color:#e3e3e3; position:absolute; z-index:1; left:0; top:0; display:none; width:100%; ..._jquery 弹出层后端获取

关于sublime3的使用-程序员宅基地

文章浏览阅读40次。一、安装Package Control使用Ctrl+`快捷键或者通过View->Show Console菜单打开命令行,粘贴如下代码:importurllib.request,os; pf ='Package Control.sublime-package'; ipp =sublime.installed_packages_path(); urllib.request.inst...

推荐文章

热门文章

相关标签