分享web开发知识

注册/登录|最近发布|今日推荐

主页 IT知识网页技术软件开发前端开发代码编程运营维护技术分享教程案例
当前位置:首页 > 代码编程

webpack

发布时间:2023-09-06 01:45责任编辑:熊小新关键词:webpack

什么是webpack

webpack是一个模块打包器,包(bundle)就是一个js文件,它把一堆资源合并在一起,以便在同一个文件请求中发回给客户端,webpack还能处理一些浏览器不能直接运行的拓展语言,如Scss,typeScript等。webpack是基于配置型的构建工具,它把整个项目作为一个整体,通过一个给定的主文件(如index.js),从这个主文件开始找到项目所有的依赖文件,使用loaders处理它们,最终打包为一个或多个浏览器可识别的js文件。

 

webpack和gulp的区别

webpack:作为一个智能解析器,几乎可以处理任何一个第三方的库,无论是commonjs,amd还是普通的js文件,甚至加载依赖的时候可以动态表达式。webpack是一种预编译的解决方案,不需要在浏览器中加载解释器,而且不管是AMD/CMD/ES6风格的模块化,它都认识,并且能编译成浏览器认识的JS。webpack是一种模块化的解决方案,webpack在很多场景下可以替代gulp/grunt类的工具 
gulp:在一个配置文件中,指明对某些文件进行类似编译、组合、压缩等任务的具体步骤,工具之后可以在自动替你完成这些任务。gulp是一个能够优化前端的开发流程的工具。

 

使用webpack

项目环境

//全局安装npm install -g webpack//安装到项目里npm install --save-dev webpack

如果项目中没有package.json这个文件,可以通过以下指令创建:

npm init

一个简单的配置文件

webpack.config.js

// 一个常见的`webpack`配置文件const 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-[hash].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: ExtractTextPlugin.extract({ ???????????????????????fallback: "style-loader", ???????????????????????use: [{ ???????????????????????????loader: "css-loader", ???????????????????????????options: { ???????????????????????????????modules: true, ???????????????????????????????localIdentName: ‘[name]__[local]--[hash:base64:5]‘ ???????????????????????????} ???????????????????????}, { ???????????????????????????loader: "postcss-loader" ???????????????????????}], ???????????????????}) ???????????????} ???????????} ???????] ???}, ???plugins: [ ???????new webpack.BannerPlugin(‘版权所有,翻版必究‘), ???????new HtmlWebpackPlugin({ ???????????template: __dirname + "/app/index.tmpl.html" //new 一个这个插件的实例,并传入相关的参数 ???????}), ???????new webpack.optimize.OccurrenceOrderPlugin(), ???????new webpack.optimize.UglifyJsPlugin(), ???????new ExtractTextPlugin("style.css") ???]};

配置分析

一 entry和output 
entry用来定义入口文件,可以是字符串或数组或对象 
1.字符串:

module.exports = { ?entry: ‘./main.js‘};

2.数组:除了main.js作为入口js之外,还有一个是用来配置webpack提供的一个静态资源服务器webpack-dev-server,它会监控项目中每个文件的变化,实时构建,并自动刷新页面。

module.exports = { ?entry: [ ???‘webpack/hot/only-dev-server‘, ???‘./main.js‘ ?]};

3.对象:将不同的文件按需构建,按需使用

module.exports = { ?entry: { ???a: ‘./a.js‘, ???b: ‘./b.js‘ ?}};

output用于定义构建后的文件的输出,是个对象,其中包含了path和filename

module.exports = { ?output: { ???path: ‘./build‘, ???filename: ‘bundle.js‘ ?}};

二 devtool 

devtool属性可以配置调试代码的方式,有多种调试方式,一般只在开发时使用,生产环境下应该将值设置为false。常用值有两个:

eval: 可以设断点调试,不显示信息,每个js模块代码用eval()执行,并且在生成的每个模块代码尾部加上注释,不 会生成.map文件。

source-map: 可以设断点调试,不显示列信息,生成相应的.Map文件,并在合并后的代码尾部加上注释//# sourceMappingURL=**.js.map,可以看到模块代码并没有被eval()包裹,此种模式并没有将调试信息放入打 包后的代码中,保持了打包后代码的简洁性.

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

上述选项由上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对打包后的文件的的执行有一定影响。cheap-module-eval-source-map推荐在大型项目考虑时间成本时使用,对小到中型的项目中,eval-source-map是一个很好的选项。

三 devserver 

如果想让你的浏览器监听你的代码修改,并自动刷新显示修改后的结果,webpack提供了一个可选的本地开发服务器,这个本地服务器基于node.js构建,可以实现你想要的这些功能,不过这是一个单独的组件,在webpack进行配置之前需要单独安装它作为项目依赖。

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

devserver有一些配置选项,可以参考如下的配置:

devserver的配置选项功能描述
contentBase默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录
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//实时刷新 ?} }

Babel 

Babel是一个编译JavaScript的平台,它可以编译代码帮你达到以下目的: 

  • 让你能使用最新的JavaScript代码(ES6,ES7),而不用管新标准是否被当前使用的浏览器完全支持;
  • 让你能使用基于JavaScript进行拓展的语言,如React的JSX;

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

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: [ ???????????????????????????"env", "react" ???????????????????????] ???????????????????} ???????????????}, ???????????????exclude: /node_modules/ ???????????} ???????] ???}};

现在你的webpack的配置已经允许你使用ES6以及JSX的语法了。

五 module

module主要是用来配置加载器(loaders)。webpack本身只能处理javascript模块,如果要处理其他类型的文件,就需要使用loader进行转换,每一种文件会用不同的加载器处理。 
loadres,preLoadres,postLoaders的配置主要包括以下几项:

    • test:一个匹配loaders所处理的文件的拓展名的正则表达式(必须)
    • loader: loader的名称(必须)
    • include/exclude: 手动添加必须处理的文件/文件夹,或屏蔽不需要处理的文件/文件夹(可选)
    • query: 为loaders提供额外的设置选项(可选)
module: { ???exprContextCritical: false, ???rules: [ ?????{ ???????test: /\.ts$/, ???????enforce: ‘pre‘, ???????loader: ‘tslint-loader‘, ???????exclude: /target/ ?????}, ?????{ ???????test: /\.tsx?$/, ???????use: [ ?????????{ ???????????loader: ‘babel-loader‘, ???????????options: { ?????????????cacheDirectory: ‘./.babelcache/‘, ?????????????plugins: [‘angularjs-annotate‘] ???????????} ?????????} ???????], ???????enforce: ‘post‘, ???????exclude: createBabelExclude() ?????}, ?????{ ???????test: /\.json$/, ???????loader: ‘json-loader‘ ?????}, ?????{ ???????test: /\.html$/, ???????loader: ‘html-loader‘ ?????}, ?????{ ???????test: require.resolve(‘highcharts‘), ???????loader: ‘expose-loader?Highcharts‘ ?????} ???] ?}

六  resolve 

resolve用来配置文件路径的指向。可以定义文件跟模块的默认路径及后缀等,节省webpack搜索文件的时间、优化引用模块时的体验。常用的包括alias,extensions,root,moduleDirectories属性。 

  • alias: 是个对象,把资源路径重定向到另一个路径
  • extensions: 是个数组,定义资源的默认后缀,比如定义后引用a.js、b.json、c.css等资源可以不用写后缀名直接写a、b、c
  • root: 是个数组,通过绝对路径的方式来定义查找模块的文件夹。可以是一个数组,主要是用来增加模块的搜寻位置使用的。root 的值必须是绝对路径,使用path.resolve设置。
  • modulesDirectories: 是个数组,用来设置搜索的目录名的,默认为["web_modules", "node_modules"]

resolve: { ???????//查找module的话从这里开始查找 ???????root: ‘E:/github/flux-example/src‘, //绝对路径 ???????//自动扩展文件后缀名,意味着我们require模块可以省略不写后缀名 ???????extensions: [‘‘, ‘.js‘, ‘.json‘, ‘.scss‘], ???????//模块别名定义,方便后续直接引用别名,无须多写长长的地址 ???????alias: { ???????????AppStore : ‘js/stores/AppStores.js‘,//后续直接 require(‘AppStore‘) 即可 ???????????ActionType : ‘js/actions/ActionType.js‘, ???????????AppAction : ‘js/actions/AppAction.js‘ ???????} ???}

七 plugins 

插件是用来拓展webpack的功能的,会在整个构建过程中生效,执行相关的任务。Loadres和Plugins是完全不同的,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less),一次处理一个,插件并不是直接操作单个文件,它直接对整个构建过程起作用。webpack有很多内置插件和第三方插件。使用某个插件,先用npm安装,然后在webpack配置的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页面,会自动添加所依赖的css,js,favicon等文件.

index.tmpl.html中的模板源代码如下:

<!DOCTYPE html><html lang="en"> ?<head> ???<meta charset="utf-8"> ???<title>Webpack Sample Project</title> ?</head> ?<body> ???<div id=‘root‘> ???</div> ?</body></html>

(3)新webpack的配置文件,方法同上,新建一个build文件夹用来存放最终的输出文件

const 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//实时刷新 ???}, ???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 一个这个插件的实例,并传入相关的参数 ???????}) ???],};

执行npm start,可以发现build文件夹下面生成了bundle.js和index.html
介绍一些常用的插件:

插件作用
extract-text-webpack-plugin第三方插件,将 CSS 打包成独立文件,而非内联。
HotModuleReplacementPlugin代码热替换
HtmlWebpackPlugin生成 HTML 文件,配合 ExtractTextPlugin 可以加入打包后的 js 和 css。
NoErrorsPlugin报错但不退出 webpack 进程。
DefinePlugin主要用来定义全局的环境变量,以便我们在自己的程序中引用它。

代码热替换 
代码热替换在开发的时候无需刷新页面即可看到更新,只在开发环境的配置文件使用,具体配置如下。

npm install --save-dev webpack-dev-server webpack-dev-middleware express

把webpack/hot/dev-server加入到 webpack 配置文件的 entry 项:

<!-- webpack.config.dev.js -->entry: [ ???‘webpack-dev-server/client?http://localhost:3000‘, ???‘./src/app.js‘],

把new webpack.HotModuleReplacementPlugin()加入到 webpack 配置文件的 plugins 项:

<!-- webpack.config.js -->plugins: [new webpack.HotModuleReplacementPlugin()]

在项目根目录新建个server.js文件,将server部分分离到一个单独的 :

<!-- server.js -->var webpack = require(‘webpack‘);var WebpackDevServer = require(‘webpack-dev-server‘);var config = require(‘./webpack.config‘);var compiler = webpack(config);var server = new WebpackDevServer(compiler, {publicPath: config.output.publicPath,hot: true,historyApiFallback: true,stats: {colors: true,hash: false,timings: true,chunks: false,chunkModules: false,modules: false}});server.listen(3000, ‘localhost‘, function(err, result) {if (err) {return console.log(err);}console.log(‘Listening at http://localhost:3000/‘);});

在 package.json 中定义启动监听热加载:

<!-- package.json -->"scripts": { ?"start": "node server.js"}

现在你可以通过运行npm start启动服务器。

webpack

原文地址:https://www.cnblogs.com/lyy-2016/p/8531102.html

知识推荐

我的编程学习网——分享web前端后端开发技术知识。 垃圾信息处理邮箱 tousu563@163.com 网站地图
icp备案号 闽ICP备2023006418号-8 不良信息举报平台 互联网安全管理备案 Copyright 2023 www.wodecom.cn All Rights Reserved