孟婆汤煨前端webpack

webpack 4.0 完全讲解及源码解读(2)

2019-05-04  本文已影响0人  公羊无衣

webpack配置

​ webpack主要是打包,所以其核心存在两个部分,入口和出口,你可以把webpack加工想象成香肠加工厂,就是活猪进去,香肠出来的那种,但是如果每次加工都需要员工亲力亲为,那多麻烦那,所以我们考虑到了自动化配置。webpack存在功能类似的配置文件,让webpack通过配置,全自动的执行我们需要的编译操作。

​ ok,我们想象一下webpack需要配置的有哪些,你可以尽情想象你是一个加工厂的小老板,此时正在配置你的香肠工厂,怎么配置最合适那?

​ webpack分成四个部分,期中最核心的就是入口和出口,当然在入口和出口配置的同时我们还需要一些加载器和插件,这就是我们所谓的webpack配置文件。这个配置文件我们习惯把其命名为webpack.config.js ,还有webpackfile.js ,为啥叫这个名字? 因为上文提到了一个叫做 help大法还记得不?

20190503.png

可以清楚的看到,这个配置文件的来源,webpack官方规定的。

​ ok,在当前项目根目录下建立了这么一个文件之后,我们马上开启webpack配置之旅。

​ 总结一下,webpack共分为四个部分,这个概念一定要记好,本文就是围绕这四个配置进行展开的 :

* 入口
* 出口
* 加载器
* 插件

基础配置

  1. 根据之前的目录我们进行基本的配置,你可以看到我们配置的语法,非常简单,有入口entry和出口output两个主要项。

const path = require('path');

module.exports = {
  entry: './src/index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
  }
};

此时我们只需要在项目文件夹命令行中输入:

webpack

不需要任何额外的内容,那么你会发现你的webpack编译成功了。同时编译时把代码压缩了起来,非常的贴心。但是美中不足的是存在一行警告 WARNING 可惜的是前面没有FBI..

WARNING in configuration
The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

​ 这么长一串警告说了啥那? 它说你现在有两种模式,一种叫做production 还有一种叫development 这两种一个都没有,这就好像是古时候文人墨客来到了青楼想要吟诗作对风流快活,妈妈桑也颤抖着脸上的肥肉向你走来,问你喜欢哪种姑娘,你却不理不睬长驱直入,坐进了天字一号房点了一杯柠檬水,还是免费的那种,这能行么 ? 人家肯定要给你警告啊,妈妈桑肯定会给你门口安排两个彪形大汉,虎视眈眈的看着你,碰到这种情况,就算知道不会挨揍,也一定不会开心,这就是我们碰到的警告。

​ 我点不就行了么!

​ webpack4新增了一个选项就是mode,必须选择是在生产环境和开发环境之中选择一个,那么我们如何选择哪?

webpack --mode development

这样选择即可,期中 -- + 参数 表示你要配置的内容是什么,后面的development 就是你传入的参数,表示开发模式,开发模式不会压缩你的代码,但是 production 模式会自动压缩你的代码,好了赶快试一下吧~,见证奇迹的时刻到了。

多入口配置

我们在很多时候需要同时引入并加载多个文件怎么办呐?这个时候你只需要在配置里有略微的更新即可。

 entry: './src/index.js',  
 //更新为 如下内容
 entry: {
      index:"./src/index.js",
      index1:"./src/index1.js"
  }

entry不仅仅可以是一个string的路径,同时也可以是一个对象,这个对象里key值作为这个入口的名称,value值作为这个入口的路径。

当然,我们如果直接运行webpack你会发现非常尴尬的问题,那就是我们的webpack报错了

多入口报错截图.png

这个报错表示人家已经有了一个叫做bundle.js的文件了,你咋还能叫budle.js那?对的可能我们之前写的代码你已经忘了,在output之中我们给文件命名为bundle.js 但是现在有两个,那也不能都叫bundle.js 吧,这就很尴尬了,于是更新一下配置:

 output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'bundle.js'
 }
 //变更为
 output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name]-[hash:6].js'
  }

这个[name] 表示以entry 的key值作为编译后的文件名,emmm,这一波很合理,也很好理解。

好了,基本配置那就这些东西,我们接着来往下聊

辅助工具篇

​ 我们打包压缩功能已经有了,但是我们还欠缺一些工具,吟诗作对么,美酒佳肴作伴是最好的,所以在这里我们给天字一号房里增加一些工具。

* devServer

首先安装一下 :

npm install --save-dev webpack-dev-server
const path = require("path");
devServer:{
    
    contentBase : path.resolve(__dirname,"dev"),
    host : "localhost",
    // 服务器压缩是否开启
    compress : true ,
    // 配置服务器端口号
    port : 8080,
    // 不打印异常信息
    quite : true,
    //开启模块热替换功能
    hot : true
    
}

tip: 这是webpack.config.js 配置文件之中的一部分内容,这是一部分内容,这是一部分内容! 要放在module.exports 后面的对象之中的内容。不是直接用的。

启动之后继续来说loader

loader

module : {

    rules : [
        {
            "test" : /\.(css|scss)$/,
            "use" : ['style-loader','css-loader','sass-loader']
        }
    ]

}

我们现在有一个目标打包css

我们先安装一个css-loader插件方便webpack进行打包

npm install css-loader -D
npm install style-loader -D

npm install sass-loader -D
npm install node-sass -D

然后我们引入css,实现一下

css-loader 会将css编译进js之中,style-loader会自动将内容引入页面。

接下来我们会将直接引入页面中的css变成,独立出来一个css文件


考虑一个问题,如何将js放入某个文件夹之中。

 entry: {
      "scripts/index":"./src/index.js",
      index1:"./src/index1.js"
}

插件 plugin

extract-text-webpack-plugin

npm install extract-text-webpack-plugin@next --dev
module : {

    rules : [
        {   
            // 加载器加载规则
            "test" : /\.(css|scss)$/,
            "use" : ExtractTextPlugin.extract({
                //是用哪个加载器作为返回接口
                fallback : "style-loader",
                //用哪个加载器进行加载
                use : ["css-loader","sass-loader"]
            })
        }
    ],
    plugins: [
        //表示将抽离出来的文件命名为什么,路径放在哪里
        new ExtractTextPlugin("styles/styles.css")
    ]

}

我们如何更新css的文件名那?

 new ExtractTextPlugin({
     filename : (getPath)=>{
         //建议打印一下  getPath('styles/[name].js') 部分内容,再进行文件替换。
         return getPath('styles/[name].js').replace("styles/scripts","app")
     }
 })

你考虑过没有,这个插件是否真的适合在开发环境之中使用那?其实并不合适,开发环境之中我们配置的倾向应该在 如何迅速而敏捷地展示我们代码的效果,需要搭建服务器,尽可能减少无用插件性能的消耗,因为我们会频繁变更代码,相信没有人希望写个前端代码需要配置一个外星人 ,而生产环境我们其实更应该倾向于 代码的压缩,代码的简化及根据需求进行产出的代码结构,在这个环境中我们无需顾及性能,因为我们不会频繁变更需要打包的代码 那么到底该如何组织我们的代码那?我们选择进行两套配置文件对其进行配置。

生产环境和开发环境

  1. 新建两个文件,一个是webpack.config.dev.js,另外一个是webpack.config.prod.js分别用于生产环境和开发环境,配置详情稍后再说。
  2. 配置我们的package.json。
"scripts":{
    "dev" : "webpack --mode development --config config/webpack.config.dev.js",
    "build" : "webpack --mode development --config config/webpack.config.prod.js"
}

我们去对两个配置文件进行更新。

html插件

html-webpack-plugin

const HtmlPlugin = require("html-webpack-plugin");

 plugins: [
        //表示将抽离出来的文件命名为什么,路径放在哪里
        new ExtractTextPlugin("styles/styles.css"),
        // html 打包出现版本号
        new HtmlPlugin({
            // 入口html;
            template : "./src/index.html",
            // 出口html
            filename : "./dist/index.html",
            //是否压缩
            minify : true
        })
]


图片打包

npm install url-loader file-loader -D
{
    test : /\.(png|jpg|git)/,
    use : [
        {
            loader:'file-loader',
            options : {
                name:"[hash:6].[ext]",
                 outputPath: 'images/',
                 publicPath: 'images/',
            }
        }
    ]
}

配置babel

安装编译工具

npm install --save-dev babel-core@next babel-loader@next babel-preset-env@next babel-preset-react@next
{
    test : /\.(jsx|js)$/,
    use : {
        loader : 'babel-loader',
        options : {
            presets : [
                "env","react"
            ]
        }
    },
    exclude:/node_modules/
}

第三方包抽离技术

entry : {
    "vendor/react":"react"
}
optimization : {
    splitChunks:{
        cacheGroups:{
            //当前路径名称
            'react' : {
                test:/react/,
                chunks: 'initial',
                name : 'vendor/react',
                priority:10
            },
            'react-dom':{
                test:/react-dom/,
                chunks:'initial',
                name : 'vendor/react',
                priority:10 
            }
        }
    }
}

上一篇下一篇

猜你喜欢

热点阅读