webpack入门

来源:互联网 发布:阿里巴巴 大数据 编辑:程序博客网 时间:2024/05/28 19:23

webpack是什么?

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

这里写图片描述

如何使用webpack?

Webpack可以使用npm安装,新建一个空的练习文件夹(此处命名为webpack sample project),在终端中转到该文件夹后执行下述指令就可以完成安装。

第一步:安装

//全局安装npm install -g webpack//安装到你的项目目录npm install --save-dev webpack

第二步:文件布置
这里写图片描述

第三步:正式使用webpack打包

方法一 : 指定命令打包
webpack {entry file} {destination for bundled file}
例如: webpack app/main.js public/bundle.js

方法二 : 配置config文件

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

在命令行中敲击 webpack 即可 , 或者在package.json中配置相关的命令执行.

webpack强大之处

1. 生成Source Maps(使调试更容易)——找出出错的位置

- source-map         在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包速度;- cheap-module-source-map  在一个单独的文件中生成一个不带列映射的map,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便; - eval-source-map使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定不要启用这个选项;

正如上表所述,上述选项由上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对打包后的文件的的执行有一定影响。

配置示范:
module.exports = {
devtool: ‘eval-source-map’,
entry: __dirname + “/app/main.js”,
output: {
path: __dirname + “/public”,
filename: “bundle.js”
}
}

2.使用webpack构建本地服务器——webpack-devserver

用途:浏览器实时监听代码变化

首先安装:

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

Webpack提供一个可选的本地开发服务器,这个本地服务器基于node.js构建

devserver的配置选项 功能描述 contentBase 默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到“public”目录) port 设置默认监听端口,如果省略,默认为”8080“ inline 设置为true,当源文件改变时会自动刷新页面 historyApiFallback 在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html

案例配置如下:

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//实时刷新  } }
package中这样配置"scripts": {    "test": "echo \"Error: no test specified\" && exit 1",    "start": "webpack",    "server": "webpack-dev-server --open"  },

在终端中输入npm run server 即自动打开本地的8080端口查看结果

3. Loaders——-转化器

Loaders需要单独安装并且需要在webpack.config.js中的modules关键字下进行配置,Loaders的配置包括以下几方面:

属性 功能 test 一个用以匹配loaders所处理文件的拓展名的正则表达式(必须) loader loader的名称(必须) include/exclude 设手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选) query 为loaders提供额外的设置选项(可选)

4.Babel的安装与配置

Babel其实是几个模块化的包,其核心功能位于称为babel-core的npm包中.
对于每一个你需要的功能或拓展,你都需要安装单独的包(用得最多的是解析Es6的babel-preset-es2015包和解析JSX的babel-preset-react包)

npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react

在webpack中配置babel如下:

module.exports = {    entry: __dirname + "/app/main.js",//已多次提及的唯一入口文件    output: {        path: __dirname + "/public",//打包后的文件存放的地方        filename: "bundle.js"//打包后输出文件的文件名    },    devtool: 'eval-source-map',    devServer: {        contentBase: "./public",//本地服务器所加载的页面所在的目录        historyApiFallback: true,//不跳转        inline: true//实时刷新    },    module: {        rules: [            {                test: /(\.jsx|\.js)$/,                use: {                    loader: "babel-loader",                    options: {                        presets: [                            "es2015", "react"                        ]                    }                },                exclude: /node_modules/            }        ]    }};

webpack会自动调用.babelrc里的babel配置选项
可以提取option中的文件放入.babelrc
如:

module.exports = {    entry: __dirname + "/app/main.js",//已多次提及的唯一入口文件    output: {        path: __dirname + "/public",//打包后的文件存放的地方        filename: "bundle.js"//打包后输出文件的文件名    },    devtool: 'eval-source-map',    devServer: {        contentBase: "./public",//本地服务器所加载的页面所在的目录        historyApiFallback: true,//不跳转        inline: true//实时刷新    },    module: {        rules: [            {                test: /(\.jsx|\.js)$/,                use: {                    loader: "babel-loader"                },                exclude: /node_modules/            }        ]    }};
{  "presets": ["react", "es2015"]}

一切皆模块

Webpack有一个不可不说的优点,它把所有的文件都都当做模块处理,JavaScript代码,CSS和fonts以及图片等等通过合适的loader都可以被处理。

css

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

//安装npm install --save-dev style-loader css-loader
//使用module.exports = {   ...    module: {        rules: [            {                test: /(\.jsx|\.js)$/,                use: {                    loader: "babel-loader"                },                exclude: /node_modules/            },            {                test: /\.css$/,                use: [                    {                        loader: "style-loader"                    }, {                        loader: "css-loader"                    }                ]            }        ]    }};

css的模块化

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

CSS预处理器

Sass 和 Less 之类的预处理器是对原生CSS的拓展,它们允许你使用类似于variables, nesting, mixins, inheritance等不存在于CSS中的特性来写CSS,CSS预处理器可以这些特殊类型的语句转化为浏览器可识别的CSS语句,

常用css预处理loader:
Less Loader
Sass Loader
Stylus Loader

我们使用PostCSS来为CSS代码自动添加适应不同浏览器的CSS前缀。
首先安装postcss-loader 和 autoprefixer(自动添加前缀的插件)

npm install --save-dev postcss-loader autoprefixer

插件(Plugins)

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

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

module.exports = {...    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('版权所有,翻版必究')    ],};

通过这个插件,打包后的JS文件显示如下
这里写图片描述

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

  plugins: [        new HtmlWebpackPlugin({            template: __dirname + "/app/index.tmpl.html"//new 一个这个插件的实例,并传入相关的参数        }),        new webpack.HotModuleReplacementPlugin()//热加载插件    ]

配置.babelrc

{  "presets": ["react", "es2015"],  "env": {    "development": {    "plugins": [["react-transform", {       "transforms": [{         "transform": "react-transform-hmr",         "imports": ["react"],         "locals": ["module"]       }]     }]]    }  }}

优化插件

  • OccurenceOrderPlugin :为组件分配ID,通过这个插件webpack可以分析和优先考虑使用最多的模块,并为它们分配最小的ID
  • UglifyJsPlugin:压缩JS代码;
  • ExtractTextPlugin:分离CSS和JS文件

OccurenceOrder 和 UglifyJS plugins 都是内置插件,你需要做的只是安装其它非内置插件

1.安装
npm install --save-dev extract-text-webpack-plugin

2.在配置文件的plugins后引用它们

// webpack.production.config.jsconst webpack = require('webpack');const HtmlWebpackPlugin = require('html-webpack-plugin');const ExtractTextPlugin = require('extract-text-webpack-plugin');module.exports = {    entry: __dirname + "/app/main.js",//已多次提及的唯一入口文件    output: {        path: __dirname + "/build",        filename: "bundle.js"    },    devtool: 'none',    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 webpack.optimize.OccurrenceOrderPlugin(),        new webpack.optimize.UglifyJsPlugin(),        new ExtractTextPlugin("style.css")    ],};

此时执行npm run build可以看见代码是被压缩后的

缓存

缓存无处不在,使用缓存的最好方法是保证你的文件名和文件内容是匹配的(内容改变,名称相应改变)

webpack可以把一个哈希值添加到打包的文件名中,使用方法如下,添加特殊的字符串混合体([name], [id] and [hash])到输出文件名前

const webpack = require('webpack');const HtmlWebpackPlugin = require('html-webpack-plugin');const ExtractTextPlugin = require('extract-text-webpack-plugin');module.exports = {..    output: {        path: __dirname + "/build",        filename: "bundle-[hash].js"    },   ...};

效果如图:
这里写图片描述

原创粉丝点击