webpack入门学习笔记

webpack学习笔记

什么是Webpack?

WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包为合适的格式供浏览器使用。

为什么要使用Webpack?

现今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,就出现了Webpack这种工具。

开始使用Webpack

安装

①进行全局安装

//全局安装
npm install -g webpack

②在项目目录中初始化

//初始化以生成package.js文件
npm init

③在项目目录中局部安装

// 局部安装Webpack
npm install --save-dev webpack

④在项目目录中新建两个文件夹,app文件夹和public文件夹,app文件夹用来存放原始数据和我们将写的JavaScript模块,public文件夹用来存放之后供浏览器读取的文件(包括使用webpack打包生成的js文件以及一个index.html文件)。接下来我们再创建三个文件:

  • index.html --放在public文件夹中;
  • Greeter.js -- 放在app文件夹中;
  • main.js -- 放在app文件夹中;

⑤我们在index.html文件中写入最基础的html代码,它在这里目的在于引入打包后的js文件。(所引入js文件例如本例中的bundle.js



  
    
    Webpack Sample Project
  
  
    

⑦在Greeter.js中定义一个返回包含问候信息的html元素的函数,并依据CommonJS规范导出这个函数为一个模块:

// Greeter.js
module.exports = function() {
  var greet = document.createElement('div');
  greet.textContent = "Hi there and greetings!";
  //这是一个DOM元素
  return greet;
};

main.js文件中写入下述代码,用以把Greeter模块返回的节点插入页面。

//main.js 
const greeter = require('./Greeter.js');
document.querySelector("#root").appendChild(greeter());

正式使用Webpack

通过配置文件来使用Webpack

定义一个配置文件,这个配置文件其实也是一个简单的JavaScript模块,我们可以把所有的与打包相关的信息放在里面。在项目的根目录下新建一个名为webpack.config.js的文件,我们在其中写入如下所示的简单配置代码:

module.exports = {
    //“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录
    entry:  __dirname + "/app/main.js",//唯一入口文件
    output: {
        path: __dirname + "/public",//打包后的文件存放的地方
        filename: "bundle.js"//打包后输出文件的文件名
    }
}

有了这个配置之后,再打包文件,只需在终端里运行webpack(非全局安装需使用node_modules/.bin/webpack)命令就可以了,这条命令会自动引用webpack.config.js文件中的配置选项。

更快捷地执行打包任务

npm可以引导任务执行,对npm进行配置后可以在命令行中使用简单的npm start命令来替代上面略微繁琐的命令。在package.json中对scripts对象进行相关设置即可,设置方法如下:

{
  "name": "webpack-sample-project",
  "version": "1.0.0",
  "description": "Sample webpack project",
  "scripts": {
    "start": "webpack" // 修改的是这里,JSON文件不支持注释,引用时请清除
  },
  "author": "zhang",
  "license": "ISC",
  "devDependencies": {
    "webpack": "3.10.0"
  }
}

npmstart命令是一个特殊的脚本名称,其特殊性表现在,在命令行中使用npm start就可以执行其对于的命令,如果对应的此脚本名称不是start,想要在命令行中运行时,需要这样用npm run {script name}npm run build

生成source maps(使调试更容易)

对小到中型的项目中,eval-source-map是一个很好的选项,不过需要注意只应该开发阶段使用它(对于打包后输出的JS文件执行具有性能和安全隐患),我们继续对上文新建的webpack.config.js,进行如下配置:

module.exports = {
  devtool: 'eval-source-map',
  entry:  __dirname + "/app/main.js",
  output: {
    path: __dirname + "/public",
    filename: "bundle.js"
  }
}

使用webpack构建本地服务器(使得浏览器实时监听代码修改,并自动刷新显示修改后的结果)

webpack中进行配置之前需要单独安装本地开发服务器

npm install --save-dev webpack-dev-server

然后修改配置文件webpack.config.js

module.exports = {
  devtool: 'eval-source-map',

  entry:  __dirname + "/app/main.js",
  output: {
    path: __dirname + "/public",
    filename: "bundle.js"
  },

  devServer: {
    //端口port要是省略,默认为8080
    contentBase: "./public",//本地服务器所加载的页面所在的目录
    historyApiFallback: true,//不跳转
    inline: true//实时刷新
  } 
}

package.json中的scripts对象中添加如下命令,用以开启本地服务器:

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack",
    "server": "webpack-dev-server --open"
  },

Loaders

Loaders的作用

通过使用不同的loaderwebpack有能力调用外部的脚本或工具,实现对不同格式的文件的处理,比如说分析转换scsscss,或者把下一代的JS文件(ES6,ES7)转换为现代浏览器兼容的JS文件,对React的开发而言,合适的Loaders可以把React的中用到的JSX文件转换为JS文件。

配置Loaders

Babel

什么是Babel?

Babel是一个编译JavaScript的平台

为什么要使用Babel?
  • 让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器完全支持;
  • 让你能使用基于JavaScript进行了拓展的语言,比如ReactJSX
Babel的安装与配置

Babel其实是几个模块化的包,其核心功能位于称为babel-core的npm包中,webpack可以把其不同的包整合在一起使用,对于每一个你需要的功能或拓展,你都需要安装单独的包(用得最多的是解析Es6的babel-preset-env包和解析JSXbabel-preset-react包)。

// npm一次性安装多个依赖模块,模块之间用空格隔开
npm install --save-dev babel-core babel-loader babel-preset-env babel-preset-react

然后在webpack中配置Babel:

module.exports = {
    devtool: 'eval-source-map',

    //“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录
    entry:  __dirname + "/app/main.js",//唯一入口文件
    output: {
        path: __dirname + "/public",//打包后的文件存放的地方
        filename: "bundle.js"//打包后输出文件的文件名
    },

    devServer:{
       contentBase:"./public",
       historyApiFallback:true,
        inline:true
    },

    module:{
        rules:[
            {
                //利用正则表达式匹配jsx和js格式文件
                test:/(\.jsx|\.js)/,
                use:{
                    loader:"babel-loader",
                    options:{
                        preset:[
                            //使得允许解析ES6和JSX语法
                            "env", "react"
                        ]
                    }
                },
                //不处理此文件夹下的文件
                exclude:/node_modules/
            }
        ]
    }
};

Babel其实可以完全在webpack.config.js中进行配置,但是考虑到babel具有非常多的配置选项,在单一的webpack.config.js文件中进行配置往往使得这个文件显得太复杂,因此一些开发者支持把babel的配置选项放在一个单独的名为 .babelrc 的配置文件中。

module.exports = {
    devtool: 'eval-source-map',

    //“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录
    entry:  __dirname + "/app/main.js",//唯一入口文件
    output: {
        path: __dirname + "/public",//打包后的文件存放的地方
        filename: "bundle.js"//打包后输出文件的文件名
    },

    devServer:{
       contentBase:"./public",
       historyApiFallback:true,
        inline:true
    },

    module:{
        rules:[
            {
                test:/(\.jsx|\.js)/,
                use:{
                    loader:"babel-loader"
                    //将options选项移至.babelrc中
                },
                exclude:/node_modules/
            }
        ]
    }
};
//.babelrc
{
  "presets": ["react", "env"]
}

CSS

CSS配置

webpack提供两个工具处理样式表,css-loaderstyle-loader,二者处理的任务不同,css-loader使你能够使用类似@importurl(...)的方法实现 require()的功能,style-loader将所有的计算后的样式加入页面中,二者组合在一起使你能够把样式表嵌入webpack打包后的JS文件中。
首先进行安装:

//安装
npm install --save-dev style-loader css-loader

接着修改webpack.config.js中的配置文件:

module.exports = {
    devtool: 'eval-source-map',

    //“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录
    entry:  __dirname + "/app/main.js",//唯一入口文件
    output: {
        path: __dirname + "/public",//打包后的文件存放的地方
        filename: "bundle.js"//打包后输出文件的文件名
    },

    devServer:{
       contentBase:"./public",
       historyApiFallback:true,
        inline:true
    },

    module:{
        rules:[
            {
                test:/(\.jsx|\.js)$/,
                use:{
                    loader:"babel-loader"
                    //将options选项移至.babelrc中
                },
                exclude:/node_modules/
            },
            {
                test:/\.css$/,
                use:[
                    {
                        loader:"style-loader"    
                    }, {
                        loader:"css-loader"
                    }
                ]
            }
        ]
    }
};

注意:我们这里例子中用到的webpack只有单一的入口,其它的模块需要通过 import, require, url等与入口文件建立其关联。

CSS module

被称为CSS modules的技术意在把JS的模块化思想带入CSS中来,通过CSS模块,所有的类名,动画名默认都只作用于当前模块。(使CSS拥有局部作用域)
配置:

module.exports = {

    ...

    module:{
        rules:[
            {
                test:/(\.jsx|\.js)$/,
                use:{
                    loader:"babel-loader"
                    //将options选项移至.babelrc中
                },
                exclude:/node_modules/
            },
            {
                test:/\.css$/,
                use:[
                    {
                        loader:"style-loader"    
                    }, {
                        loader:"css-loader",
                        options:{
                            modules:true, //指定启用css modules
                            localIdentName: '[name]__[local]--[hash:base64:5]' //指定css的类名格式
                        }
                    }
                ]
            }
        ]
    }
};

使用:
先将要使用的CSS文件引入,例如:

import styles from './Greeter.css';

然后在需要使用的地方通过以下方式调用:

//使用cssModule添加类名的方法
CSS预处理器

首先安装postcss-loaderautoprefixer(自动添加前缀的插件)

npm install --save-dev postcss-loader autoprefixer

接下来在webpack.config.js中添加postcss-loader

module.exports = {

    ...

    module:{
             rules:[
                 {
                     test:/(\.jsx|\.js)$/,
                     use:{
                         loader:"babel-loader"
                         //将options选项移至.babelrc中
                     },
                     exclude:/node_modules/
                 },
                 {
                     test:/\.css$/,
                     use:[
                         {
                             loader:"style-loader"    
                         }, {
                             loader:"css-loader",
                             options:{
                                 modules:true, //指定启用css modules
                                 localIdentName: '[name]__[local]--[hash:base64:5]' //指定css的类名格式
                             }
                         }, {
                             loader:"postcss-loader"                    
                         }
                     ]
                 }
             ]
         }
};

再之后在根目录新建postcss.config.js,并添加如下代码之后,重新使用npm start打包,css将会自动添加前缀。

// postcss.config.js
module.exports = {
    plugins: [
        require('autoprefixer')
    ]
}

插件(Plugins)

Plugins和Loaders的区别

Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSXScssLess..),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程其作用。

使用插件的方法

要使用某个插件,我们需要通过npm安装它,然后要做的就是在webpack配置中的plugins关键字部分添加该插件的一个实例。(plugins是一个数组)

常用插件
HtmlWebpackPlugin

这个插件的作用是依据一个简单的index.html模板,生成一个自动引用你打包后的JS文件的新index.html。这在每次生成的js文件名称不同时非常有用(比如添加了hash值)。
首先进行插件的安装:

npm install --save-dev html-webpack-plugin

安装完成之后,如果是依照以上教程流程部署环境的话,那么就得修改原先的项目结构:

  1. 移除public文件夹,利用此插件,index.html文件会自动生成,此外CSS已经通过前面的操作打包到JS中了。
  2. 在app目录下,创建一个index.tmpl.html文件模板,这个模板包含title等必须元素,在编译过程中,插件会依据此模板生成最终的html页面(如index.tmpl.html),会自动添加所依赖的 css, js,favicon等文件。
  3. 在这之后,需要在webpack.config.js中配置添加的插件:
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

    ...
    
    module:{
             rules:[
                 {
                     test:/(\.jsx|\.js)$/,
                     use:{
                         loader:"babel-loader"
                         //将options选项移至.babelrc中
                     },
                     exclude:/node_modules/
                 },
                 {
                     test:/\.css$/,
                     use:[
                         {
                             loader:"style-loader"    
                         }, {
                             loader:"css-loader",
                             options:{
                                 modules:true, //指定启用css modules
                                 localIdentName: '[name]__[local]--[hash:base64:5]' //指定css的类名格式
                             }
                         }, {
                             loader:"postcss-loader"                    
                         }
                     ]
                 }
             ]
    },
    plugins:[
        new HtmlWebpackPlugin({
            //传入相关参数
            template:__dirname + "/app/index.tmpl.html"
        })
    ]
};
  1. 新建一个build文件夹存放最终输出文件(需要修改webpack.config.js),然后再次运行npm start就行了。

这篇文章是我参考学习(copy)别人webpack入门教程的时候写下的,写时对文章内容还有不是很理解的地方,需要之后再次阅读。更加具体的内容请参考教程原文:zhangwang的webpack入门教程。

你可能感兴趣的:(webpack入门学习笔记)