美文网首页
关于webpack(webpack 4.0版本)

关于webpack(webpack 4.0版本)

作者: codingHi | 来源:发表于2021-02-15 00:20 被阅读0次

    查看版本:webpack -v

    一、什么是webpack?

    可以看做是模块打包机(一种模块化的解决方案)也是一个打包工具。

    二、webpack的工作方式

    把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。

    Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。

    image.png

    三、webpack相关文件

    package.json文件:npm说明文件,里面蕴含丰富信息,包括当前项目的依赖模块,自定义的脚本任务。

    在终端使用npm init命令可以自动创建这个package.json文件(输入这个命令后,终端会问你一系列诸如项目名称,项目描述,作者等信息node,如果你不准备在npm中发布你的模块,这些问题的答案都不重要,回车默认即可)

    四、webpack的安装

    package.json文件就绪后,在项目中安装Webpack作为依赖包

    npm install -g webpack                //全局安装
    npm install --save-dev webpack       //安装到你的项目目录
    
    npm info webpack    可以查看webpack版本信息
    

    运行过程中如果出现:webpack:command not found,请检查是否在全局环境下安装webpack,全局环境下安装webpack使用命令:npm install webpack -g

    不推荐全局安装 webpack。这会将你项目中的 webpack 锁定到指定版本,并且在使用不同的 webpack 版本的项目中,可能会导致构建失败。 ---来自webpack官网

    五、webpack搭建

    1.npm install webpack --save-dev
    2.npm init   //初始化package.json文件
    3.npm install webpack-cli --save-dev   //CLI(命令行工具)已经转移到了一个单独的包webpack-cli中。 
    4.创建src目录并新建index.js  写入一段代码。 //webpack4.x默认是以项目根目录下的'./src/index.js'作为入口,因此我们在根目录下创建src文件夹。
      function hello(str) { alert(str); } 
      hello('hello world!');
    5.输入webpack --mode development命令或者webpack --mode production命令打包   //就可以将'./src/index.js'打包成'./dist/main.js'。 
    # 注意:webpack4.x的打包已经不能用webpack 文件a 文件b的方式,例如:webpack index.js bundle.js 命令
    # 而是直接运行webpack --mode development或者webpack --mode production,这样便会默认进行打包,
    # 入口文件是'./src/index.js',  输出路径是'./dist/main.js',
    # 其中src目录即index.js文件需要手动创建,而dist目录及main.js会自动生成。 
    6.不过每次都要输入这个命令,非常麻烦,我们在package.json中scripts中加入两个成员:
    "dev":"webpack --mode development", 
    "build":"webpack --mode production"
    之后运行 npm run dev即可打包
    7.配置其他参数
    在webpack –mode production/development后加上其他参数即可例如:
    webpack --mode development --watch --progress --display-modules --colors --display-reasons
    当然,这也可以写入package.json的scripts之中。
    

    六、webpack中的各种loader

    1.什么是loader

    用法参考:https://webpack.docschina.org/concepts/loaders/#
    Loader 可以理解为是模块或资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过 require 来加载任何类型的模块或文件,比如 CoffeeScript、 JSX、 LESS 或图片。

    • loaders是你用在app源码上的转换元件。他们是用node.js运行的,把源文件作为参数,返回新的资源的函数。
    • loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
    • 处理一个文件可以使用多个loader,loader的执行顺序是和本身的顺序是相反的,即最后一个loader最先执行,第一个loader最后执行。
    • 第一个执行的loader接收源文件内容作为参数,其他loader接收前一个执行的loader的返回值作为参数。最后执行的loader会返回此模块的JavaScript源码

    2.loader的安装:npm install xxx-loader -save-dev

    3.loader的三种用法:

    ①require() (可以在 require() 引用模块的时候添加)

    a.在hello.js中通过require引用style.css,执行webpack hello.js hello.bundle.js,报错如下图:


    image.png
    报错信息

    报错提示需要一个loader转换器来处理css样式

    b.输入命令:npm install css-loader style-loader --save-dev,来安装css的loader转换器和style的loader转换器
    安装完成后,输入命令:webpack hello.js hello.bundle.js,进行编译hello.js
    s运行发现仍然发现报错


    image.png

    c.查看引入style.css的地方,webpack只能处理javascript模块,处理css需要借助于loader转换器
    在require() 引用模块的时候添加loader转换
    那么在require引入style.css文件时,就需要css-loader转换。require('css-loader!./style.css');


    image.png

    在进行编译打包hello.js,编译打包成功


    image.png

    查看hello.bundle.js文件,多出了css样式这一块,并且css样式为一独立模块


    image.png

    d.在项目目录下新建一个index.html,并且引入hello.js打包后的hello.bundle.js


    image.png

    e.修改hello.js,运行hello()函数,接着再编译一次hello.js到hello.bundle.js


    image.png
    image.png

    f.运行index.html,页面上弹出“hello world!”
    j.但是我们发现页面的背景色并没有变成ccc的样式,要想让css样式生效,还需要在require引入css的时候使用style-loader
    require('style-loader!css-loader!./style.css');
    编辑完后再用webpack编译打包


    image.png
    image.png

    h.刷新index页面,页面变成了ccc的背景色

    image.png
    发现style.css中的样式被使用style标签插入到了head里面,这是由style-loader实现的
    css-loader是允许webpack识别.css的文件
    style-loader是将webpack识别完的css文件中的内容,在编译完运行文件的时候,将这些css用style标签包起来嵌在head内
    上面的例子讲述的都是在require引入模块的时候添加的loader转换,还有一种方式就是在命令行中添加loader,其他和上面讲述一样
    ②在配置文件webpack.config.js中通过module.loaders进行配置 (可以在 webpack 全局配置中进行绑定)
    ③在命令行中配置 (可以通过命令行的方式使用)

    在命令行中添加loader
    在命令行中输入命令:webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader'
    (git bash中执行相当于linux,如在windows下的cmd估计要将单引号换成双引号)
    去掉hello.js中require时添加的loader依赖,并将上面的命令进行编译

    image.png
    image.png
    每次修改完文件进行编译时都需要写命令,很是繁琐,在命令最后加上--watch,当文件有变化时,就会自动编译
    webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader' --watch
    image.png
    当修改hello.js文件保存后,就会看到命令行上已经重新编译
    image.png
    刷新index.html就可以看到修改后的内容了

    七、webpack其他命令介绍:

    --progress:当前打包的进度条
    --display-modules:打包的模块,依赖什么而打包也会列出来
    --display-reasons:打包模块的原因,因为什么打包
    输入完整命令:webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader' --progress --display-modules --display-reasons --watch
    当检测到文件有变化时进行编译,编译输出包括打包进度、打包模块、打包原因


    image.png

    congratulation到这里,loader的使用已经开始入门了!

    八、package-lock.json到底是干嘛的?

    原来package.json文件只能锁定大版本,也就是版本号的第一位,并不能锁定后面的小版本,你每次npm install都是拉取的该大版本下的最新的版本,
    npm最新的版本开始提供自动生成package-lock.json功能

    package-lock.json锁定依赖包版本,当用户在另外一台电脑或者新环境下,只要按照package-lock.json所标示的具体版本下载依赖库包,就能确保所有库包与你上次安装的完全一样。

    这里举个例子:
    "dependencies": {
    "@types/node": "^8.0.33",
    },
    这里面的 向上标号^是定义了向后(新)兼容依赖,指如果 types/node的版本是超过8.0.33,并在大版本号(8)上相同,就允许下载最新版本的 types/node库包,例如实际上可能运行npm install时候下载的具体版本是8.0.35

    那如果我们安装时的包有bug,后面需要更新怎么办?
    在以前可能就是直接改package.json里面的版本,然后再npm install了,但是5版本后就不支持这样做了,因为版本已经锁定在package-lock.json里了,
    所以我们只能npm install xxx@x.x.x 这样去更新我们的依赖,然后package-lock.json也能随之更新。

    注意:在直接更新package.json和package-loc.json这两个文件后,npm install是可以直接覆盖掉原先的版本的,所以在协作开发时,这两个文件如果有更新,你的开发环境应该npm install一下才对。

    九、前端工程项目的NODE_ENV

    在package.json的scripts命令内容和webpack配置文件中可以看到NODE_ENV这个变量,它的值可以是development或product,也有人简写为'dev'或'prod'。
    这个变量表示构建项目的当前环境,也就是我们的程序会跑在生产环境、测试环境还是开发环境,
    node中有全局变量process表示当前node进程,process.env包含着关于系统环境的信息。但是process.env中并不存在NODE_ENV这个东西。其实NODE_ENV只是一个用户自定义的变量。
    当我们在服务启动时配置NODE_ENV,或在代码中给process.env.NODE_ENV赋值,js便能通过process.env.NODE_ENV获取信息。
    那么,这个变量的赋值在哪里设置呢?很多开发者将NODE_ENV=XXXX放到项目package.json的scripts命令中:

    "scripts": {
        "build-win": "SET NODE_ENV=production && webpack --config build/webpack.config.js",
        "build": "EXPORT  NODE_ENV=production && webpack --config build/webpack.config.js"
     }
    

    也有人会在webpack配置文件中对NODE_ENV作默认值处理,如果scripts.build||script.start脚本没有设置NODE_ENV,缺省值为'development'.
    NODE_ENV: process.env.NODE_ENV || 'development',
    不同平台下的设置区别?
    在类unix系统和安装并使用了bash的windows的系统上,我们会使用:

    "EXPORT  NODE_ENV=production && webpack --config build/webpack.config.js"
    

    在windows系统上,我们使用:

    "SET NODE_ENV=production && webpack --config build/webpack.config.js"
    

    有的人嫌麻烦,为了屏蔽两种系统间的这个区别,会引用第三方插件cross-env

    {
      "scripts": {
        "build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
      }
    }
    

    只要在NODE_ENV前面加上cross-env标志,会根据当前系统类型帮你选择适当的指令给NODE_ENV赋值。

    mode选项:
    在mode为production或development的状态下,为了兼顾两个状态下的程序运行,webpack创建了一个全局变量process.env.NODE_ENV,等同于在插件plugins中加入了

    new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development|production") })
    

    用来区分不同的状态,同时可以在程序中区分程序状态。
    那么我们该如何在coding的时候进行区分呢?因为process.env.NODE_ENV是全局变脸给,所以可以这样来引用值,假设mode:production:

    if ("development" === process.env.NODE_ENV){ .... }else{ .... }
    

    编译之后:

    if ("development" === "production"){ .... }else{ .... }
    

    也就是最后process.env.NODE_ENV会被替换为一个常量。这个小功能可以帮助我们在写业务JS的时候,区分线上版本与开发版本。

    相关文章

      网友评论

          本文标题:关于webpack(webpack 4.0版本)

          本文链接:https://www.haomeiwen.com/subject/aqeyxltx.html