webpack 配置学习笔记

来源:互联网 发布:mac禁止程序自动启动 编辑:程序博客网 时间:2024/06/10 06:35

webpack 入门 大全学习笔记

  1. 新建文件夹,命名 webpack project,在命令行中找到此位置。使用:
    //全局安装    npm install webpack -g     //安装到项目目录     npm install webpacl --save-dev
  1. 在新建package.json 文件,这是一个标准的 npm 说明文件。在命令行输入npm init 即可自动生成本文件(文件生成过程中所需参数均可不填);
  2. 回到之前的空文件夹,并创建 app 与 piblic 两个文件夹。其中 app文件夹存放原始数据和我们将写的JavaScript模块。public 文件夹用来存放之后后浏览器读取的文件(包括使用webpack 打包生成的js文件以及一个 index.html 文件)。接下来再创建三个文件夹中:
    • index.html –放在public文件夹中;
    • Greeter.js –放在app文件夹中;
    • main.js –放在app文件夹中。
      在 index.html 中写入最基本的html代码,它在这里的目的在于引入打包之后的js文件。
//index.html<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>webpack test</title></head><body>    <div id="root">    </div>    <script type="text/javascript" src="bundle.js"></script></body></html>

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

//Greete.jsmodule.exports = function(){    var greet = document.createElement('div');    greet.textContent = "Hi this from Greeter.js";    return greet;}

在main.js 文件中 引入Greeter.js文件,并添加到html文件中。

//main.jsconst greeter = require('./Greeter.js');documemt.querySelector('#root').appendChild(greeter());

正式使用 webpack

webpack 可以在终端使用,基本使用方法如下:

# {extry file}出填写入口文件的路径,本文中就是上述main.js的路径,# {destination for bundled file}处填写打包文件的存放路径# 填写路径的时候不用添加{}webpack {entry file} {destination for bundled file}

配置webpack

在练习文件夹下新建 webpack.config.js ,写入一下基本配置:

module.exports = {    entry:__dirname + "/app/main.js",//入口文件    output:{        path:__dirname +"/public/",//打包后的文件存放的地方        filename:"bundle.js" //打包后输出文件夹的名字    }}

设置完毕后,只需在命令行中输入 webpack 执行,即可。
继续对 npm 进行配置后可以在命令行中使用简单的 npm start 命令来替代上述命令。在 package.json文件中 对 scripts对象进行相关设置即可,设置方法如下:

// + 代表新增。- 代表删除 "scripts": {    "test": "echo \"Error: no test specified\" && exit 1", +   "start":"webpack"  },

webpack 的强大功能

生成Source Maps (使调试更容易)

webpack.config.js 中进行配置:

module.exports = {+   devtool: 'eval-source-map',    entry: __dirname + "/app/main.js", //入口文件    output: {        path: __dirname + "/public/", //打包后的文件存放的地方        filename: "bundle.js" //打包后输出文件夹的名字    }}

使用webpack 构建本地服务器

让浏览器监听你的代码的修改,并自动刷新显示后的结果。安装组件:

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

继续配置 webpack.config.js

module.exports = {    devtool: 'eval-source-map',    entry: __dirname + "/app/main.js", //入口文件    output: {        path: __dirname + "/public/", //打包后的文件存放的地方        filename: "bundle.js" //打包后输出文件夹的名字    },+   devServer: {+       contentBase: "./public/", //本地服务器所加载的页面所在的目录+       historyApiFallback: true, //不跳转+       inline: true, //实时刷新+       //  port:8080 //设置监听端口。默认8080;    }}

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

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

在命令行中输入npm run server 即可在本地的8080(默认端口)查看结果。

Loaders

Loaders 需要单独安装并且需要在webpack.config.js 中的 modules 关键字下进行配置。Loaders 的配置包括以下几个方面:
- test:一个用以匹配loaders所处理文件的扩展名的正则表达式(必须);
- loader:loader的名称(必须);
- include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选);
- query:为loaders提供额外的设置选项(可选).

不过在配置loader之前,我们把`Greeter.js`里的问候消息放在一个单独的`JSON`文件里,并通过合适的配置使`Greeter.js`可以读取该`JSON`文件的值,各文件修改后的代码如下:在 public文件中创建如下 JSON 文件(命名为:`config.json`):
{    "greetText":"Hi this message from /public/config.json"}

更新后的 Greeter.js

+ var config = require('../public/config.json');module.exports = function() {    var greet = document.createElement('div');+   greet.textContent = config.greetText;    return greet;}

Babel 的安装与配置

一次性的安装依赖包:

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

在webpack 中的webpack.config.js 添加如下配置:

+ module: {+       rules: [{+           test: /(\.jsx|\.js)$/,+           use: {+               loader: "babel-loader",+               options: {+                   presets: ["es2015", "react"]+               }+           },+           exclude: /node_modules/+       }]+   }

安装 react 以及 reactdom:
接下来使用ES6 的语法,更新Greeter.js,并返回一个React组件:

+ import React,{Component} from 'react'+ import config from '../public/config.json';+ class Greeter extends Component{+   render(){+       return(+           <div>+           {config.greetText}+           </div>+           );+   }+ }+ export default Greeter

修改main.js如下:

+ import React from 'react';+ import {render} from 'react-dom';+ import Greeter from './Greeter'+ render(<Greeter />, document.getElementById('root'));

重新使用npm start打包,会在http://localhost:8080/看到相应输出。这说明react 和 es6 被正常打包了。

一切皆模块

CSS

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

继续在webpack.config.js中添加module配置:

    module: {        rules: [{            。。。},    +   {    +       test:/\.css$/,    +       use:[{    +           loader:"style-loader"    +       },{    +           loader:"css-loader"    +       }]    +   }]    }

接下来,在app文件夹中创建一个名字为“main.css”的文件,设置一些样式:

html{    box-sizing: border-box;    -ms-text-size-adjust:100%;    -webkit-text-size-adjust:100%;}*,*:before,*:after{    box-sizing: inherit;}body{    margin:0;    font-family: "Helvetica Neue",Helvetica,Arial,sans-serif;}h1,h2,h3,h4,h5,h6,p,ul{    margin:0;    padding:0;}

我们这里例子中用到的webpack只有单一的入口,其它的模块需要通过 import, require, url等与入口文件建立其关联,为了让webpack能找到”main.css“文件,我们把它导入”main.js“中,如下:

//main.js+ import './main.css'; //导入css文件。

上面的代码说明webpack是怎么把css当做模块看待的,咱们继续看一个更加真实的css模块实践。

CSS module

最近有一个叫做 CSS modules 的技术就意在把JS的模块化思想带入CSS中来,通过CSS模块,所有的类名,动画名默认都只作用于当前模块。Webpack从一开始就对CSS模块化提供了支持,在CSS loader中进行配置后,你所需要做的一切就是把”modules“传递到所需要的地方,然后就可以直接把CSS的类名传递到组件的代码中,且这样做只对当前组件有效,不必担心在不同的模块中使用相同的类名造成冲突。具体的代码如下:

//webpack.config.js{            test: /\.css$/,            use: [{                loader: "style-loader"            }, {                loader: "css-loader",+               options:{+                   modules:true+               }            }]        }

继续:
在app文件夹下创建一个Greeter.css文件:

.root{    background-color: #eee;    padding:10px;    border:3px solid #ccc;}

导入 .rootGreeter.js中:

import React, {Component} from 'react'import config from '../public/config.json';+ import styles from './Greeter.css'; //导入css样式class Greeter extends Component {    render() {        return (+           <div className={styles.root}>             {config.greetText}            </div>        );    }}export default Greeter

在命令行中打包,在打开index.html文件查看效果。

CSS 预处理器

css 预处理器可以将特殊类型的语句转化为浏览器可识别的CSS语句。
在 webpack 里使用相关 loaders进行配置就可以使用了。以下是常用的CSS 处理loaders:
- Less Loader
- Sass Loader
- Stylus Loader
还有一个 PostCSS,可以帮助CSS实现更多功能。举例来说,使用PostCSS为CSS代码自动添加适应不同浏览器的CSS 前缀。
首先安装postcss-loaderautoprefixer(自动添加前缀的插件)

npm install postss-loader autoprefixer --save-dev

接下来,在webpack 配置文件webpack.config.js中添加postcss-loader,在根目录新建 postcss.config.js,并添加如下代码之后,重新使用 npm start打包时,写的css会自动根据 Can i use 里的数据添加不同前缀了。

//webpack.config.js    module: {        rules: [{            。。。}, {            test: /\.css$/,            use: [{                loader: "style-loader"            }, {                loader: "css-loader",                options: {                    modules: true                }            },{+               loader:"postcss-loader"            }]        }]    }
//postcss.config.js+ module.exports = {+   plugins: [+       require('autoprefixer')+   ]+ }

插件(Plugins)

插件(Plugins)是用来拓展Webpack功能的,它们会在整个构建过程中生效,执行相关的任务。
Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个,插件并不直接操作单个文件,它直接对整个构建过程其作用。

使用插件的方法

要使用某个插件,需要使用 npm 安装它,然后要做的就是在 webpack配置中的plugins 关键字部分添加该插件的一个实例(plugins 是一个数组),继续上面的例子。给其添加一个给打包后代码添加版权声明的插件(BannerPlugin)

+ const webpack = require('webpack'); module.exports = {     。。。     module:{     。。。     },+    plugins: [+       new webpack.BannerPlugin('版权所有,翻版必究')+   ]}

HtmlWebpackPlugin

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

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

这个插件自动完成了我们之前手动做的一些事情,在正式使用之前需要对一直以来的项目结构做一些更改:
1. 移除public文件夹。利用此插件,index.html文件会自动生成。此外,css已经通过前面的操作打包到js中了。
2. 在app目录下,创建一个 index.tmpl.html 文件模板,这个模板包含 title 等必须元素,在编译过程中,插件会依据此模板生成最终的html 页面,会自动添加所以来的css,js,favicon, index.tmpl.html 中的模板源代码如下:

<!DOCTYPE html><html lang="en"><head>    <meta charset="UTF-8">    <title>webpack test module</title></head><body>        <div id="root">        </div></body></html>
  1. 更新webpack的配置文件:添加plugin及其参数,修改output输出文件目录,修改devServer的目录。方法同上,新建一个 build 文件夹用来存放最终的输出文件。
//webpack.config.js+ const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {    。。。    output: {+       path: __dirname + "/build/", //打包后的文件存放的地方        filename: "bundle.js" //打包后输出文件夹的名字    },    devServer: {+       contentBase: "./build/", //本地服务器所加载的页面所在的目录        historyApiFallback: true, //不跳转        inline: true, //实时刷新        //  port:8080 //设置监听端口。默认8080;    },    plugins: [        new webpack.BannerPlugin('版权所有,翻版必究'),+       new HtmlWebpackPlugin({+           template: __dirname + "/app/index.tmpl.html" //new 一个这个插件的实例,并传入相关的参数+       })    ]}

修改,app文件夹下的Greeter.js 文件:

- import config from './public/config.json';+ import config from './config.json';

在本目录新建 config.json ,内同同public文件中中的config.json。
执行 npm start会在build 文件夹下面发现bundle.js index.html两个文件。

Hot Module Replacement

Hot Module Replacement(HMR)也是webpack里很有用的一个插件,它允许你在修改组件代码后,自动刷新实时预览修改后的效果。
在webpack中实现HMR也很简单,只需要做两项配置:
- 在webpack配置文件中添加HMR插件;
- 在 webpack Dev Server中添加“hot”参数;
不过配置完这些后,JS模块其实还是不能自动热加载的,还需要在你的JS模块中执行一个Webpack提供的API才能实现热加载,虽然这个API不难使用,但是如果是React模块,使用我们已经熟悉的Babel可以更方便的实现功能热加载。
整理下我们的思路,具体实现方法如下

Babel和webpack是独立的工具
- 二者可以一起工作
- 二者都可以通过插件拓展功能
- HMR是一个webpack插件,它让你能浏览器中实时观察模块修改后的效果,但是如果你想让它工作,需要对模块进行额外的配额;
- Babel有一个叫做react-transform-hrm的插件,可以在不对React模块进行额外的配置的前提下让HMR正常工作;
继续上例,进行配置:

//webpack.config.js    devServer: {        contentBase: "./build/", //本地服务器所加载的页面所在的目录        historyApiFallback: true, //不跳转        inline: true, //实时刷新+       hot:true,        //  port:8080 //设置监听端口。默认8080;    },    plugins: [        new webpack.BannerPlugin('版权所有,翻版必究'),        new HtmlWebpackPlugin({            template: __dirname + "/app/index.tmpl.html" //new 一个这个插件的实例,并传入相关的参数        }),+       new webpack.HotModuleReplacementPlugin() //热加载插件    ]

安装 react-transform-hmr

npm install babel-plugin-react-transform react-transform-hmr --save-dev

由于babel配置增加,所以新建.babelrc 文件来统一babel配置设置。

//.babelrc{    "presets":["react","es2015"],    "env":{    "development":{    "plugins":[["react-transform",{        "transforms":[{            "transform":"react-transform-hmr",            "imports":["react"],            "locals":["module"]    }]    }]]    }    }}
//webpack.config.jsrules: [{            test: /(\.jsx|\.js)$/,            use: {                loader: "babel-loader",-               // options: {-               //  presets: ["es2015", "react"]-               // }            },            exclude: /node_modules/        },{...}]

现在当你使用React时,可以热加载模块了,每次保存就能在浏览器上看到更新内容。

产品阶段的构建

目前为止,我们已经使用webpack构建了一个完整的开发环境。
但是在产品阶段,可能还需要对打包的文件进行额外的处理,比如说优化,压缩,缓存以及分离CSS和JS。
对于复杂的项目来说,需要复杂的配置,这时候分解配置文件为多个小的文件可以使得事情井井有条,以上面的例子来说,我们创建一个webpack.production.config.js的文件,在里面加上基本的配置,它和原始的webpack.config.js很像,如下:

// webpack.production.config.jsconst webpack = require('webpack');const HtmlWebpackPlugin = require('html-webpack-plugin');module.exports = {    entry: __dirname + "/app/main.js",//已多次提及的唯一入口文件    output: {        path: __dirname + "/build",        filename: "bundle.js"    },    devtool: 'eval-source-map',    devServer: {        contentBase: "./public",//本地服务器所加载的页面所在的目录        historyApiFallback: true,//不跳转        inline: true,        hot: true    },    module: {        rules: [            {                test: /(\.jsx|\.js)$/,                use: {                    loader: "babel-loader"                },                exclude: /node_modules/            },            {                test: /\.css$/,                use: [                    {                        loader: "style-loader"                    }, {                        loader: "css-loader",                        options: {                            modules: true                        }                    }, {                        loader: "postcss-loader"                    }                ]            }        ]    },    plugins: [        new webpack.BannerPlugin('版权所有,翻版必究'),        new HtmlWebpackPlugin({            template: __dirname + "/app/index.tmpl.html"//new 一个这个插件的实例,并传入相关的参数        }),        new webpack.HotModuleReplacementPlugin()//热加载插件    ],};
//package.json{  "name": "webpackproject",  "version": "1.0.0",  "description": "for webpack test",  "main": "index.js",  "dependencies": {    "react": "^15.6.1",    "react-dom": "^15.6.1",    "webpack": "^3.5.4"  },  "devDependencies": {    "autoprefixer": "^7.1.2",    "babel-core": "^6.25.0",    "babel-loader": "^7.1.1",    "babel-plugin-react-transform": "^2.0.2",    "babel-preset-es2015": "^6.24.1",    "babel-preset-react": "^6.24.1",    "css-loader": "^0.28.4",    "html-webpack-plugin": "^2.30.1",    "postcss-loader": "^2.0.6",    "react-transform-hmr": "^1.0.4",    "style-loader": "^0.18.2",    "webpack-dev-server": "^2.7.1"  },  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1",    "start": "webpack",    "server": "webpack-dev-server --open",    "build": " set NODE_ENV=production &&webpack --config ./webpack.production.config.js --progress",  },  "author": "wang",  "license": "ISC"}

优化插件

通过npm安装。一下插件可以完成产品发布阶段所需的功能:
- OccurenceOrderPlugin:为组件分配ID,通过这个插件webpack 可以分析和优先考虑使用最多的模块,并未他们分配最小的ID。
- UglifyJsPlugin:压缩JS代码;
- ExtractTextWebpackPlugin:分离CSS和JS文件;
继续使用上例查看如何添加他们。OccurenceOrder 和 UglifyJS plugins 都是内置插件,你需要做的只是安装其它非内置插件:

npm install --save-dev extract-text-webpack-plugin

在配置文件中的plugins后引用他们:

//webpack.production.config.jsconst ExtractTextPlugin = require("extract-text-webpack-plugin");module.exports = {  module: {    rules: [      {        test: /\.css$/,+                   use: ExtractTextPlugin.extract({+                   fallback: "style-loader",+                   use: [-                           // {-                       // loader: "style-loader"-                       // },{                        loader: "css-loader",                        options: {                            modules: true                        }                    }, {                        loader: "postcss-loader"                    }]                })      }    ]  },  plugins: [    new ExtractTextPlugin("styles.css"),  ]}

这是在命令行中运行“npm run build” 可以看到在“build”文件夹下新生成了“style.css”文件。

原创粉丝点击