Node.js   发布时间:2022-04-24  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了webpack从此不再是我们的痛点 — 核心基础大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。

1.webpack是什么?

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。并且跟具你的项目中的各种需求,实现自动化处理,解放我们的生产力

2.项目初始化

@H_176_26@mkdir webpack-start cd webpack-start npm init

3.webpack核心概念

  • Entry:入口,webpack执行构建的第一步将从Entry开始,可抽象理解为输入
  • @H_921_9@module:模块,在webpacl中一切皆为模块,一个模块对应一个文件,webpack会从配置的Entry开始递归找出所有依赖的模块
  • Chunk:代码块,一个chunk由多个模块组合而成,用于将代码合并和分割
  • Loader:模块转换器,用于把模块原内容按照需求转换为需要的新内容
  • Plugin:扩展插件,在webpack构建流程中的特定时机注入扩展逻辑来改变构建结果和想要做的事情
  • Output:输入结果,在webpack经过一系列处理并得到最终想要的代码然后输出结果
1.Entry
@H_176_26@module.exports = { context: path.join(__dirname,'..'),// 找到根目录 entry: './main.js' //根目录下的入口文件 } @H_176_26@module.exports = { entry: './main.js' }
entry: {
  home: "./home.js",about: "./about.js",contact: "./contact.js"
}

如果是单页面(传入的是字符串或字符串数组),则chunk会被命名为main,如果是多页面(传入一个对象),则每个键(key)会是chunk的名称,描述了chunk的入口起点

2.output
  • path:输出目录对应一个绝对路径

    path: path.resolve(__dirname,'dist')
  • pathinfo:Boolean false作用是告诉webpack在bundle中引入所包含模块信息的相关注释,不应用于生产环境(production),对开发环境(development)极其有用
  • publicPath:主要作用是针对打包后的文件里面的@L_616_48@路径处理
  • filename:定义每个输出bundle的名称,这些bundle将写入output.path选项指定的目录下,对于单入口Entry,filename一个静态名称

    filename: "bundle.js"

    但是在webpack中我们会用到代码拆分、各种插件plugin或多入口Entry创建多个bundle,这样我们就应该给每个bundle一个唯一的名称

    filename: "[name].bundle.js"

    使用内部chunk id

    filename: "[id].bundle.js"

    唯一hash生成

    filename: "[name].[hash].bundle.js"

    使用基于每个 chunk 内容的 hash

    filename: "[chunkhash].bundle.js"
3.Module模块
  • @H_831_6@module.noParse: 防止webpack解析的时候,将规则匹配成功的文件进行解析和忽略大型的library来对性能的优化,在被忽略的文件中不应该含有import、require和define的调用

    @H_176_26@module.exports = { module: { rules: [],noParse: function(content) { return /jquery|lodash/.test(content) // 忽略jquery文件解析,直接编译打包 } } }
  • Rules:创建模块时,匹配请求的规则数组

    • Rule条件:resource(请求文件绝对路径)、issuer(被请求资源的模块文件绝对路径,导入时的位置),比如一个文件A导入文件B,resource是/B,issuer是/A是导入文件时的位置,而不是真正的位置,在规则中,test/include/exclude/resource对resource匹配,而issuer只对issuer匹配
    • Test/include/exclude/resource/issuer的用法和区别

      @H_176_26@module.exports = { modules: { rules: [ { test: /\.js?$/,include: [ path.resolve(__dirname,"app") ],exclude: [ path.resolve(__dirname,"app/demo") ],resource:{ test: /\.js?$/,include: path.resolve(__dirname,"app"),exclude: path.resolve(__dirname,"app/demo") },issuer: { test: /\.js?$/,"app/demo") } } ] } }

      text:一般是提供一个正则表达式或正则表达式的数组,绝对路径符合这个正则的则意味着满足这个条件

      include:是一个字符串或者字符串数组,指定目录中的文件需要走这个规则

      exclude:同样是一个字符串或者字符串数组,指定目录中的文件不需要走这个规则

      resource:就是对text/include/exclude的一个对象包装,和他们单独写没有区别

      issuer:和resource有异曲同工的作用,不过区别在于它是将这个rule应用于哪个文件以及这个文件所导入的所有依赖文件

    • resourceQuery:和resource用法一样,不过针对的是匹配结果'?'后面的路径参数,可以调用resource中的text等
    • oneOf:表示对该资源只应用第一个匹配的规则,一般结合resourceQuery

      {
        test: /\.(png|jpe?g|gif|svg)$/,oneOf: [
          {
            resourceQuery: /inline/,loader: 'url-loader'
          },{
            loader: 'file-loader'
          }
        ]
      }
      • path/to/foo.png?inline: 会匹配url-loader
      • path/to/foo.png?other:会匹配file-loader
      • path/to/foo.png: 会匹配file-loader
    • useEntry:object包含着每一个loader并且对应loader的配置文件

      {
        loader: "css-loader",options: {
          modules: true
        }
      }

      options会传入loader,可以理解为loader的选项

    • use:是对useEntry的集合,并且对每一个入口指定使用一个loader

      use: [
        'style-loader',{
          loader: 'css-loader',options: {
            importLoaders: 1
          }
        },{
          loader: 'less-loader',options: {
            noIeCompat: true
          }
        }
      ]
4.Resolve解析
  • alias:object主要用来让import和require调用更方便,设置初始路径

    @H_176_26@module.exports = { alias: { Utilities: path.resolve(__dirname,'src/utilities/'),Templates: path.resolve(__dirname,'src/templates/') } } // 最开始的import import Utility from '../../utilities/utility'; // 配置完以后 import Utility from 'Utilities/utility';
  • enforceExtension:Boolean false,表示引用不需要扩展名,为true时,import、require中引用必须加扩展名
  • extensions:Array 自动解析不需要扩展名

    extensions: [".js",".json"]  // .js、.json引入不需要扩展名
  • @H_831_6@modules:Array webpack解析模块的时候需要搜索的目录,一般用于优先搜索和非node_modules文件中的自定义模块

    @H_176_26@modules: [path.resolve(__dirname,"src"),"node_modules"] //优先搜索src目录
5.Loader
@H_176_26@module: { rules:[ { test:/\.css$/,use:['style-loader','css-loader'],include:path.join(__dirname,'./src'),exclude:/node_modules/ } ] }

具体相关loader需要查看你要引入的loader官方文档API,手写Loader会在下一篇文章具体介绍

6.Plugin插件
7.webpack-dev-server
8.Devtool
9.Watch

4.配置webpack

webpack安装命令

npm install webpack webpack-cli -D

Webpack.config.js

  • clean-webpack-plugin:用于打包前清空输出目录 官方API
  • html-webpack-plugin:用于自动产出HTML和引用产出的资源 官方API
  • copy-webpack-plugin:用于拷贝静态资源,包括未被引用的资源 官方API
  • uglifyjs-webpack-plugin:用于压缩JS可以让输出的JS文件体积更小、加载更快、流量更省,还有混淆代码的加密功能 官方API
  • extract-text-webpack-plugin:因为CSS的下载和JS可以并行,当一个HTML文件很大的时候,我们可以把CSS单独提取出来加载 官方API
const path = require('path');
const webpack = require('webpack');
const cleanWebpackPlugin = require('clean-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const copyWebpackPlugin = require('copy-webpack-plugin');
const UglifyjsWebpackPlugin = require('uglifyjs-webpack-plugin')
// npm i extract-text-webpack-plugin@next // @next可以安装下一个非正式版本
const ExtractTextWebpackPlugin = require('extract-text-webpack-plugin');
let cssExtract = new ExtractTextWebpackPlugin({
    filename: 'css/css.css',allChunks: true
});
let lessExtract = new ExtractTextWebpackPlugin('css/less.css');
let sassExtract = new ExtractTextWebpackPlugin('css/sass.css');
/**
 * 有些时候我们希望把页面中的CSS文件单独拉出来保存加载
 * extract-text-webpack-plugin
 */
//let pages = ['index','base'];
// pages = pages.map(page => new HtmlWebpackPlugin({
//     template: './src/index.html',//指定产的HTML模板
//     filename: `${pagE}.html`,//产出的HTML文件名
//     title: `${pagE}`,//     chunks: ['common',`${pagE}`],//在产出的HTML文件里引入哪些代码块
//     hash: true,// 会在引入的js里加入查询字符串避免缓存,//     minify: {
//         removeAttributeQuotes: true
//     }
// }));
module.exports = {
    //先找到每个入口(Entry),然后从各个入口分别出发,找到依赖的模块(ModulE),
    //然后生成一个Chunk(代码块),最后会把Chunk写到文件系统中(Assets)   
    entry: './src/main.js',output: {
        path: path.join(__dirname,'dist'),//输出文件夹,只能是绝对路径 
        //name是entry名字main,hash根据打包后的文件内容计算出来的一个hash值
        filename: '[name].[hash].js' //打包后的文件名
    },resolve: {
        //引入模块的时候,可以不用扩展名 
        extensions: [".js",".less",".json"],alias: {//别名
            "bootstrap": "bootstrap/dist/css/bootstrap.css"
        }
    },//表示监控源文件的变化,当源文件发生改变后,则重新打包
    watch: false,watchOptions: {
        ignored: /node_modules/,poll: 1000,//每秒钟询问的次数
        aggregateTimeout: 500//
    },//devtool: 'source-map',//单独文件,可以定位到哪一列出错了
    // devtool: 'cheap-module-source-map',//单独文件,体积更小,但只能定位到哪一行出错
    // devtool: 'eval-source-map',//不会生成单独文件,
    // devtool: 'cheap-module-eval-source-map',//不会生成单独文件 只定位到行,体积更小
    /*
    loader有三种写法
    use
    loader
    use+loader
    * */
    module: {
        rules: [
            {
                test: require.resolve('jquery'),use: {
                    loader: 'expose-loader',options: '$'
                }
            },{
                test: /\.js/,use: {
                    loader: 'babel-loader',query: {
                        presets: ["env","stage-0","react"]
                    }
                }
            },{
                //file-loader是解析图片地址,把图片从源位置拷贝到目标位置并且修改原引用地址
                //可以处理任意的二进制,bootstrap 里字体
                //url-loader可以在文件比较小的时候,直接变成base64字符串内嵌到页面中
                test: /\.(png|jpg|gif|svg|bmp|eot|woff|woff2|ttf)/,loader: {
                    loader: 'url-loader',options: {
                        limit: 5 * 1024,//指定拷贝文件输出目录 
                        outputPath: 'images/'
                    }
                }
            },{
                test: /\.css$/,//转换文件的匹配正则
                //css-loader用来解析处理CSS文件中的url路径,要把CSS文件变成一个模块
                //style-loader 可以把CSS文件变成style标签插入head中
                //多个loader是有顺序要求的,从右往左写,因为转换的时候是从右往左转换
                //此插件先用css-loader处理一下css文件
                //如果压缩
                loader: cssExtract.extract({
                    use: ["css-loader?minimize"]
                })
                //loader: ["style-loader","css-loader","postcss-loader"]
            },{
                test: /\.less$/,loader: lessExtract.extract({
                    use: ["css-loader?minimize","less-loader"]
                })
                //use: ["style-loader","less-loader"]
            },{
                test: /\.scss$/,loader: sassExtract.extract({
                    use: ["css-loader?minimize","sass-loader"]
                })
                // use: ["style-loader","sass-loader"]
            },{
                test: /\.(html|htm)/,loader: 'html-withimg-loader'
            }
        ]
    },plugins: [
        //用来自动向模块内部注入变量
        // new webpack.ProvidePlugin({
        //     $: 'jquery'
        // }),new UglifyjsWebpackPlugin(),new CleanWebpackPlugin([path.join(__dirname,'dist')]),//此插件可以自动产出html文件
        new HtmlWebpackPlugin({
            template: './src/index.html',//指定产的HTML模板
            filename: `index.html`,//产出的HTML文件title: 'index',hash: true,minify: {
                removeAttributeQuotes: true
            }
        }),new CopyWebpackPlugin([{
            from: path.join(__dirname,'public'),to: path.join(__dirname,'dist','public')
        }]),cssExtract,lessExtract,sassExtract
    ],//配置此@L_616_48@服务器,可以用来预览打包后项目
    devServer: {
        contentBase: './dist',host: 'localhost',port: 8000,compress: true,//服务器返回给浏览器的时候是否启动gzip压缩
    }
}

5.总结

6.博客

魏燃技术博客

有任何问题可留言或者发送本人邮箱ngaiwe@126.com

大佬总结

以上是大佬教程为你收集整理的webpack从此不再是我们的痛点 — 核心基础全部内容,希望文章能够帮你解决webpack从此不再是我们的痛点 — 核心基础所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。