• webpack


    1、现代web开发的问题:

    1)采用模块化开发,但是不同的浏览器对于模块化的支持不一样,模块化本身又存在多种规范

    2)使用新特性例如es+或者ts来编写代码,提高效率保证安全性,也会用sass,less来编写css,浏览器在默认情况下也不能处理

    3)实时监听开发过程,使用热更新

    4)项目编码完成后,在部署之前需要对代码进行压缩处理

    为了解决这些问题,使得开发者可以随意使用想用的技术栈进行项目开发,最终结果可以在浏览器直接展示,因此就会用到打包工具,我们项目使用的react,vue,angular等框架本身就集成了webpack,所以看似没配置,但是其实功能你已经在用了。

    2、定义

    是为现代js应用提供静态模块打包的工具

    可以将不同类型资源按模块处理进行打包

    打包后最终产出静态资源,最终产出的内容可以直接部署在静态服务器上使用

    webpack支持不同规范的模块化开发,例如esmodule,commonjs,amd规范等

    3、本地安装webpack+webpack-cli

    utils.js

    const sum = (m, n) => {

            return m+n;

    }

    const square = (m) => {

            return m*m;

    }

    export {sum, square};

    index.js

    import {sum, square} from './js/utils.js';

    console.log(sum(1,2));

    console.log(square(3));

    index.html手动导入Js文件

            

    打开浏览器发现报错了,这里使用的是esmodule规范

    解决办法:

    index.html手动导入Js文件

            

    但是这不能解决根本问题,比如:

    api.js commonjs规范

    const getInfo = () => {

            return {

                    name: 'lql',

                    age: 20

            }

    }

    module.exports = getInfo;

    index.js

    const getInfo = require('./js/getInfo.js');

    console.log(getInfo());

    这时候我们就需要有个能帮我们把这些规范都统一一下的东西,那就是webpack

    终端执行npx webpack,会产生一个dist目录,这是因为webpack会默认找到./src/index.js作为入口,

    修改index.html中的代码

            

    回到浏览器就不报错了

    4、终端命令行配置入口entry和出口output

    将index.js重命名main.js,再次执行npx webpack会报错,所以就需要用到一些配置

    npx webpack --entry ./src/main.js终端执行这个命令就不会报错啦

    npx webpack --entry ./src/main.js --output-path ./build终端执行这个命令修改输出目录

    终端命令比较麻烦,所以可以通过一下方式:

    终端执行npm run build即可

    5、新建webpack.config.js文件,配置入口和出口

    module.exports = {

            entry: './src/index.js',

            output: {

                    filename: 'build.js',

                    path: './dist/main.js' // 这个有问题,会报错

            }

    }

    修改package.json文件中的build值为webpack即可

    这时候执行npm run build会报错

    原因是:

    Webpack的错误信息指出了配置对象中的一个问题,具体是关于 output.path 的。这个错误告诉我们提供的值 ./dist/main.js 不是一个绝对路径。

    在Webpack中,output.path 是用来指定输出文件的目录的,而且必须是一个绝对路径。绝对路径是从文件系统的根目录开始的完整路径,例如 /user/project/dist

    解决这个问题的方法是确保 output.path 的值是一个绝对路径。你可以通过两种方式来实现:

    1. 使用绝对路径: 直接指定输出目录的绝对路径,例如 /user/project/dist

    2. 使用Node.js内置的路径解析模块: 在Webpack配置文件中使用Node.js内置的path模块来生成绝对路径。例如:

      const path = require('path');
      module.exports = {

          // 其他配置...
          output: {
              path: path.resolve(__dirname, 'dist'),
              filename: 'main.js'
          },
          // 其他配置...
      };

    path.resolve(__dirname, 'dist') 将会生成当前Webpack配置文件所在目录下的 dist 目录的绝对路径。

    webpack.config.js

    const path = require('path');

    module.exports = {

            entry: './src/index.js',

            output: {

                    filename: 'build.js',

                    // path: './dist/main.js'

                    path: path.resolve(__dirname, 'dist')

            }

    }

    这样的话npm run build就没问题啦

    6、为什么使用loader?

    不是所有的文件都能被打包,就需要loader来进行文件的转换。默认只能打包js文件。

    css-loader只是能让webpack可以识别我们的css语法,并不能在元素上生效对应的css样式,需要安装style-loader

    6.1、css-loader

    npm i css-loader

    使用有两种方式:

    1)行内

    2)配置文件

    npm i style-loader安装好style-loader后,

    执行npm run build会报错

    这个问题跟loader的执行顺序有关系,代码现在写的他会先style-loader进行处理,然后结果被传递给css-loader,之后css-loader处理后把结果重新交给compare对象进行打包操作,执行顺序默认从右到左,所以说修改下顺序就可以解决问题了

    这时候你在执行npm run build 就没有报错啦,而且页面上样式已经生效了

    6.2、style-loader

    作用就是在界面中生成一个style标签

    新建login.less文件

    安装npm i less -D

    less编译为css?

    npx less ./src/css/login.less loginLessToCss.css终端执行命令后,会生成一个loginLessToCss.css文件,就是Less文件所编译成的css文件

    但是不可能说我有好多个less文件,都这样执行命令,所以安装less-loader

    6.2、less-loader

    7、项目工程化,兼容性:css js 一些特性如何实现兼容?到底要兼容哪些平台(caniuse.com是根据这个网站看的)?

    node-modules里有一个包browserlist,配置需要兼容的平台

    终端执行npx browserslist命令可以得到符合条件的平台

    也可以新建.browserslistrc文件

    8、postcss?做一些兼容性处理  browserlist提供条件
    8.1、postcss是什么?

    用JavaScript工具和插件转换CSS的工具。它的主要功能是将CSS代码转换为抽象语法树(AST),然后通过插件对AST进行操作和转换,最后再将AST转换回CSS代码。PostCSS的灵活性使得开发者可以编写自定义的插件来处理各种CSS相关的任务,比如自动添加浏览器前缀(autoprefixer插件)、支持新的CSS语法等。利用js转换样式的工具

    8.2、如何使用?

    安装postcss:npm i postcss,

    要想直接通过行内或者终端的方式npx postcss是不允许的,需要再装一个包,npm i postcss-cli

    新建css文件  一个网站autoprefixer.github.io

    test.css文件

    .example {

            transition:all .5s;

            uer-select:none;

            background:linear-gradient(to bottom, white, black);

    }

    8.3、使用场景(样式无法做到兼容)

    这三个样式不是所有的浏览器都能兼容,所以希望有这么一个工具帮我们自动添加前缀,实现兼容

    安装postcss-cli,然后终端使用命令:npx postcss -o ret.css ./src/css/test.css

    这时候发现没有用,并没有实现兼容,原因是postcss还需要一些插件的支持,现在想要一个加前缀的插件npm i autoprefixer

    这时候终端执行npx postcss --use autoprefixer -o ret.css ./src/css/test.css根据browserlistrc文件内的条件进行兼容处理,这时候ret.css文件里就有兼容处理了

    9、postcss-loader,兼容css样式,比如加前缀

    当css文件中有一些可能在不同浏览器是不能做到完全兼容的样式时,做一些特殊处理

    这时候安装npm i postcss-loader

    webpack配置文件中修改加了postcss-loader,打开浏览器页面发现没有加上前缀,是因为我们需要添加插件

    10、postcss-preset-env,不同插件的集合

    当我们修改css文件中color:#12345678时,因为16进制常见的是6位,但这里是8位,在谷歌浏览器没有问题,但别的浏览器可能会有兼容问题

    当我们使用babel的时候,会遇见postcss-preset-env,会说这是预设,是不同插件的集合

    安装npm i postcss-preset-env

    这样你再执行npm run build就会发现color: #12345678变成了color:rgba();的格式

    简写

    这样的代码有些冗余,可以单独放在一个配置文件中,方便通用性配置的管理

    新建文件postcss.config.js

    11、importLoaders属性

    当我们有个css1文件,这个文件里没有需要兼容性处理的代码,而另一个文件css2里有需要做兼容性的代码,css1文件内通过@import './css2.css'的方式引入,发现并没有做兼容性处理,原因是因为先postcss-loader,然后css-loader才会处理@import 或者url()这种的css文件,他会自动的把他替换为require语法,但是css-loader并没有兼容处理的能力,所以导致这个问题,这时候就需要引入importLoaders

    12、file-loader打包图片(一种img标签设置src,一种css设置background:url)

    方式一:img标签设置src

    新建Image.js文件,src下新建img文件夹,放点图片

    在Index.js文件中

    //开始file-loader的展示

    import './js/Image.js';

    执行npm run build,发现报错了

    安装npm i file-loader -D,修改webpack配置

    新增

    {

            test: /\.(png|svg|gif|jpe?g)$/,

            use: ['file-loader']

    }

    再次执行npm run build,

    src的值之所以是这样,是因为Image.js中我们用require('../img/smile.png')的原因

    解决办法

    1、

    .default,这是因为file-loader升级后要适配webpack5的原因

    2、不加.deault,而是修改webpack的配置,不让转化为esModule

    3、不修改webpack配置,而是通过import的方式导入

    方式二:css设置background:url

    npm run build后发现页面没展示

    原因是定位到的图片是

    原因解释:在遇到css-loader处理css文件时,遇到url会替换成require语法,所以应该是要有个.default的,但是url在css文件里,又不支持.default的写法,所以只能修改webpack

    再次执行npm run build,发现没问题了

    12.1、如何对file-loader打包后的图片的结果进行一些处理?

    执行npm run build后查看dist文件夹

    13、url-loader处理图片

    安装npm i url-loader -D

    执行npm run build,页面展示没问题,但是dist下边没目录了

    13.1、file-loader与url-loader处理图片的区别?

    file-loader:把我们当前的图片名称或者路径返回,及打包后的图片资源直接拷贝到dist目录下

    url-loader:把我们要打包的图片资源以base64uri的方式加载到代码中

    可以审查下元素

    url-loader好处就是减少了请求的次数,但也有风险,如果图片资源较大,那这种方式就不好了

    在url-loader内部可以调用file-loader

    14、asset(无需安装,webpack5自带)处理图片

    asset module type

    1)asset/resource 相当于file-loader

    2)asset/inline 相当于url-loader

    3)asset/source 相当于raw-loader

    4)asset 设置配置参数动态配置

    这种设置执行npm run build会展示

    如果想对打包后的结果进行一些配置,有两种方式

    1)全局配置

    npm run build后发现可以了

    全局不方便

    2)局部配置

    15、asset处理图标字体

    新建font文件夹存放iconfont库

    新建Font.js

    index.js文件中引入

    npm run build发现报错了,因为缺少可以处理iconfont的loader

    配置loader

    npm run build 没问题

    16、webpack插件plugin

    loader:是对特定的模块类型做一个转换

    插件:可以做更多的事情,可以用于执行范围更广的任务。包括:打包优化,压缩处理,资源管理,注入环境变量。

    想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中

    16.1、clean-webpack-plugin:自动清空dist文件夹

    安装npm i clean-webpack-plugin -D

    npm run build就会自动清空dist文件夹了

    16.2、plugin:html-webpack-plugin 自动打包生成静态资源xxx.html文件

    dist文件夹下会自动生成静态html文件

    新建public文件夹,下边新建index.html

    webpack文件配置

    npm run build后dist文件夹下的index.html

    17、定义常量DefinePlugin,webpack自带,设置BASE_URL

    比如vue项目生成的public文件夹

    给我们这个index.html替换下

    npm run build会报错

    原因是因为会把./原封不动拿过来给BASE_URL,但是我们期望的是个字符串,所以说加个""就可以了

    18、babel:转换在项目中使用的JSX,TS,ES6+这些语法

    为什么前端会用到babel?

    比如我有个react项目,那我在项目中使用的JSX,TS,ES6+这些语法,默认浏览器是不能直接识别的。我们要转化为浏览器平台能直接使用的,就会用babel工具

    安装npm i @babel/core -D

    想在命令行使用,就安装@babel/cli

    命令输入npx babel src --out-dir build 会生成一个build文件夹,但发现build文件夹内的内容跟之前es6的语法没有区别,这时候就还需要安装一个工具包npm i @babel/plugin-transform-arrow-functions -D

    终端执行npx babel src --out-dir build --plugins=@babel/plugin-transform-arrow-functions

    发现build文件夹内的Index.js就已经转换成普通函数了

    还有const 转 var

    npm i @babel/plugin-transform-block-scoping   -D

    npx babel src --out-dir build --plugins=@babel/plugin-transform-arrow-functions,@babel/plugin-transform-block-scoping  

    这多麻烦,那么多玩意儿要转呢,所以也需要想postcss-preset-env这样的一个预设集合的存在,一窝端

    18.1、@babel/preset-env预设集合

    npm i @babel/preset-env -D

    npx babel src --out-dir build --presets=@babel/preset-env

    18.2、babel-loader 转浏览器不支持的js语法

    一个一个引入太麻烦,直接把预设放在这

    那什么浏览器会被兼容这种转换的规则呢,就得说回.browserslistrc文件了,跟这里边的有关系

    那还有一个可以配置的地方

    target这个更优先

    简洁方法,新建一个babel.config.js

    19、polyfill:打补丁  webpack5优化打包速度,所以移除了,需要的话得安装

    是什么?当代码遇见promise,generator,symbol等时,@babel/preset-env不一定有用,所以要用polyfill打一个补丁

    安装npm i core-js regenerator-runtime

    三个值:

    false默认,不对当前js做polyfill

    usage,依据用户代码当中所使用的新语法进行polyfill

    entry,依据浏览器平台进行polyfill

    加上corejs: 3是因为不加报错了,需要指定下corejs的版本

    可能node_modules里边有别的用到了polyfill的地方,那填充的就有冲突了,所以使用babel-loader时要配置下

    20、plugin: copy-webpack-plugin 资源拷贝 例如public文件下的favicon.icon的拷贝,不需要打包,直接帮我拷贝一下就好

    npm i copy-webpack-plugin -D

    21、webpack-dev-server

    是一个webpack提供的开发服务器工具,用于在开发过程中快速启动一个本地服务器并实时监视文件变化,自动重新编译和刷新页面。它能够提供实时的代码变化反馈,同时支持热模块替换(HMR),使开发者能够更高效地进行前端开发。

    打包完成后想要修改代码后同步实现页面的更新,两种方式:

    1)

    2)

    但是这种效率不是最优的,现在的模式是watch+vscode的插件live server实现的,相对于webpack-dev-server有些不足:

    1.所有的原代码都会重新编译

    2.每次编译成功之后都需要进行文件读写,都要进行磁盘交互

    3.webpack本身具有live server的实现

    4.组件化开发时,如果只是部分组件更新,会导致全部更新,但webpack有热更新实现局部更新

    安装npm i webpack-dev-server

    终端执行npm run serve,默认起了一个服务,端口是8080,并没有产生dist文件夹,是因为放在内存了,而不是磁盘的读写

    22、webpack-dev-middleware

    安装npm i express webpack-dev-middleware

    新建server.js文件

    这时候通过localhost:3000也可以访问页面啦

    23、webpack5中的HMR模块热替换功能

    浏览器只需要对局部发生变化的数据进行展示即可,

    在开发阶段应该把.browserslistrc内容给屏蔽掉,再加上热更新功能

    默认还是刷新整个页面进行工作的,但是我们不期望这样,所以应该在入口文件中把想要进行热更新的文件给他写上

    24、react项目支持热更新功能

    安装npm i @babel/preset-react react react-dom

    新建page文件夹,新建App.jsx文件

    但是更新image.js有热更新,而修改App.jsx文件的值就没有热更新,而是重新刷新了页面

    npm i @pmmmwh/react-refresh-webpack-plugin react-refresh -D --force

    这时候执行npm run serve发现都实现了热更新

    25、vue项目支持热更新

    安装 npm i vue@2.6.14 vue-template-compiler@2.6.14 -D

    新建App.vue文件

    vue-loader15版本之前可以直接处理,之后需要自己加个插件

    26、path
    1)output中的path与publicPath

    output:{

            path:告知webpack把资源产出到哪个目录下

            publicPath:''(默认''没有的话浏览器会帮我们加/)告知index.html假如内部引用了什么资源,你应该怎么找到引用路径(域名+publicPath+filename)

            如果是'/'比较奇怪:

            npm run serve发现没问题

            但是如果通过dist下的index.html然后open deault browser会发现找不到js资源,原因是因为最好还是写成publicPath:'./',但是./这种方式通过npm run serve发现又不行了

    }

    比如说npm run serve后,http://localhost:8080/js/login.js

    注意:如果我们开发阶段用webpack-dev-serve去开启一个本地服务的操作对资源进行访问,那么我们更加关注的是publicPath,所以空字符串或者'/'都可以,但是'/'npm run build就会有问题

    2)devServer中的publicPath:告知浏览器指定本地服务所在的目录

    得一样

    publicPath这里是/lg,那不可能通过http://local:8080来访问到,得再加个/lg

    contentBase有这样一个使用场景,在public文件夹下有一个工具js文件,这个文件我不希望被webpack打包,只是帮我拷贝一下就行,但是打包后的index.html又引用到了这个工具文件,这时候就得通过contentBase来找path.resolve(__dirname, 'public')绝对路径,因为这个工具文件在public下,跟contentBase配套的一个配置,用于监控资源是否更新,watchContentBase: true

    27、dev-Server的配置

    hotOnly的存在原因:当页面中存在很多组件,当一个组件可能出现一些语法错误时,当我们发现问题并且修改后,发现会因为这一个组件导致整个页面进行了刷新,这样不好,所以出现了hotOnly:true

    port:4000重启一个端口

    open:true会自动打开页面

    compress:true压缩,性能提升

    historyApiFallback: true的使用场景,页面通过路由实现页面跳转,当从home跳转到about,再刷新about页面会找不到,这时候加上这个配置就可以了

    28、devServer本地开发设置proxy请求代理

    4000端口的服务去请求服务端的接口,然后把数据给前端

    29、resolve配置模块解析规则

    分为三种情况:

    绝对路径

    相对路径:根据路径,路径确定了,往后就看他是文件夹还是文件,文件就看有没有明确后缀,如果没有,就是extensions里的.js,.json,如果是文件夹,默认会给他补全,index

    模块:找node_modules下的模块就行

    webpack配置

    29.1、extensions:解析后缀名

    29.2、alias:创建 import 或 require 的别名,来确保模块引入变得更简单

    30、source-map

    mode的值默认是production,npm run build后会比较优化,

    如果改为mode: 'development',打包后会更加便于阅读,打包后的文件里会有个eval()的包裹,原因是因为当设置为development模式后,相当于加了个devtool:'eval'

    devtool:控制是否生成,以及如何生成 source map

    30.1、为什么需要source-map?

    当我开发过程中如果语法有一些错误,执行npm run serve后会看到控制台报错,但是报错的定位是打包后的js文件,我们无法快速定位到问题出在哪里,这时候就需要source-map了,是个映射技术,可以依据转换之后的代码,返还成原代码

    便于调试,打包后会多一个.js.map

    31、devtool详细说明

    值:

    eval

    souce-map

    eval-souce-map

    inline-source-map 少一次请求,不会生成.js.map文件

    cheap-source-map 定位错误只会有行信息,没有列信息,而且会优化,比如说代码空的行会被删除等

    cheap-module-source-map 原本的代码定位

    hidden-source-map 有.js.map文件 文件内也没有sourceMappingURL信息,定位错误时文件名是打包后的文件名了,定位不到源代码文件

    nosources-souce-map 有.js.map文件 只有错误提示,没有源代码定位文件

    vue框架使用的是source-map

    react框架使用的是cheap-module-source-map

    32、ts-loader编译ts

    全局安装npm i ts,会生成ts compiler解析器

    终端执行tsc --init,当前目录下会生成tsconfig.json文件

    安装npm i ts-loader

    33、babel-loader编译ts

    用到一个预设

    npm i @babel/preset-typescript

    babel-loader在代码打包npm run build时如果有语法错误不会报错,但是在运行阶段会报错

    ts-loader在代码打包npm run build时如果有语法错误会报错

    解决办法?

    使用babel-loader

    在package.json文件内新增

    这样就会在打包之后进行ts检查

    34、区分打包环境

    webpack-merge

    项目代码:

    const projectName = process.env.ENV_PROJECT || process.argv[2]; // 项目名称

    process.argv

    webpack.base.config.js

  • 相关阅读:
    前端_Vue_1.初识Vue
    dpdk igbuio基础信息
    Linux - Ubuntu里安装指定版本的package
    [深度学习] 名词解释--正则化
    java读取配置文件
    1.12 字典(Python)
    前后端分离项目(十一):实现"删"功能(前后端)
    SpringBoot之Dockerfile
    GPIO子系统编写LED驱动
    linux下tomcat容器基本使用方法
  • 原文地址:https://blog.csdn.net/qq_44307861/article/details/137869454