• [技术干货] freemarker运算符 函数等指令
    其它指令1.3.2.1 运算符1 、算数运算符 FreeMarker表达式中完全支持算术运算,FreeMarker支持的算术运算符包括:+, - , * , / , %2、逻辑运算符 逻辑运算符有如下几个: 逻辑与:&& 逻辑或:|| 逻辑非:! 逻辑运算符只能作用于布尔值,否则将产生错误3 、比较运算符 表达式中支持的比较运算符有如下几个: 1 =或者==:判断两个值是否相等. 2 !=:判断两个值是否不等. 3 >或者gt:判断左边值是否大于右边值 4 >=或者gte:判断左边值是否大于等于右边值 5 <或者lt:判断左边值是否小于右边值 6 <=或者lte:判断左边值是否小于等于右边值注意: =和!=可以用于字符串,数值和日期来比较是否相等,但=和!=两边必须是相同类型的值,否则会产生错误,而且FreeMarker是精确比较,"x","x ","X"是不等的.其它的运行符可以作用于数字和日期,但不能作用于字符串,大部分的时候,使用gt等字母运算符代替>会有更好的效果,因为 FreeMarker会把>解释成FTL标签的结束字符,当然,也可以使用括号来避免这种情况,如:<#if (x>y)>1.3.2.2 空值处理1 、判断某变量是否存在使用 “??” 用法为:variable??,如果该变量存在,返回true,否则返回false例:为防止stus为空报错可以加上判断如下: <#if stus??> <#list stus as stu> ...... </#list> </#if>2 、缺失变量默认值使用 “!” 使用!要以指定一个默认值,当变量为空时显示默认值。例: ${name!''}表示如果name为空显示空字符串。如果是嵌套对象则建议使用()括起来。例: ${(stu.bestFriend.name)!''}表示,如果stu或bestFriend或name为空默认显示空字符串。1.3.2.3 内建函数内建函数语法格式: 变量+?+函数名称1 、和到某个集合的大小${集合名?size}2 、日期格式化显示年月日: ${today?date} 显示时分秒:${today?time} 显示日期+时间:${today?datetime} <br> 自定义格式化: ${today?string("yyyy年MM月")}3 、内建函数cmap.put("point", 102920122);point是数字型,使用${point}会显示这个数字的值,不并每三位使用逗号分隔。如果不想显示为每三位分隔的数字,可以使用c函数将数字型转成字符串输出${point?c}4 、将json字符串转成对象一个例子:其中用到了 assign标签,assign的作用是定义一个变量。<#assign text="{'bank':'工商银行','account':'10101920201920212'}" /> <#assign data=text?eval /> 开户行:${data.bank} 账号:${data.account}1.3.2.4 完整的模板上边测试的模板内容如下,可自行进行对照测试。<!DOCTYPE html> <html> <head> <meta charset="utf‐8"> <title>Hello World!</title> </head> <body> Hello ${name}! <br/> <table> <tr> <td>序号</td> <td>姓名</td> <td>年龄</td> <td>钱包</td> </tr> <#list stus as stu> <tr> <td>${stu_index + 1}</td> <td <#if stu.name =='小明'>style="background:red;"</#if>>${stu.name}</td> <td>${stu.age}</td> <td >${stu.mondy}</td> </tr> </#list> </table> <br/><br/> 输出stu1的学生信息:<br/> 姓名:${stuMap['stu1'].name}<br/> 年龄:${stuMap['stu1'].age}<br/> 输出stu1的学生信息:<br/> 姓名:${stu1.name}<br/> 年龄:${stu1.age}<br/> 遍历输出两个学生信息:<br/> <table> <tr> <td>序号</td> <td>姓名</td> <td>年龄</td> <td>钱包</td> </tr> <#list stuMap?keys as k> <tr> <td>${k_index + 1}</td> <td>${stuMap[k].name}</td> <td>${stuMap[k].age}</td> <td >${stuMap[k].mondy}</td> </tr> </#list> </table> </br> <table> <tr> <td>姓名</td> <td>年龄</td> <td>出生日期</td> <td>钱包</td> <td>最好的朋友</td> <td>朋友个数</td> <td>朋友列表</td> </tr> <#if stus??> <#list stus as stu> <tr> <td>${stu.name!''}</td> <td>${stu.age}</td> <td>${(stu.birthday?date)!''}</td> <td>${stu.mondy}</td> <td>${(stu.bestFriend.name)!''}</td> <td>${(stu.friends?size)!0}</td> <td> <#if stu.friends??> <#list stu.friends as firend> ${firend.name!''}<br/> </#list> </#if> </td> </tr> </#list> </#if> </table> <br/> <#assign text="{'bank':'工商银行','account':'10101920201920212'}" /> <#assign data=text?eval /> 开户行:${data.bank} 账号:${data.account} </body> </html>1.3.3 静态化测试在cms中使用freemarker将页面生成html文件,本节测试html文件生成的方法:1 、使用模板文件静态化定义模板文件,使用freemarker静态化程序生成html文件。2 、使用模板字符串静态化定义模板字符串,使用freemarker静态化程序生成html文件。1.3.3.1 使用模板文件静态化在test下创建测试类,并且将main下的resource/templates拷贝到test下,本次测试使用之前我们在main下创建的模板文件。//基于模板生成静态化文件 @Test public void testGenerateHtml() throws IOException, TemplateException { //创建配置类 Configuration configuration=new Configuration(Configuration.getVersion()); //设置模板路径 String classpath = this.getClass().getResource("/").getPath(); configuration.setDirectoryForTemplateLoading(new File(classpath + "/templates/")); //设置字符集 configuration.setDefaultEncoding("utf‐8"); //加载模板 Template template = configuration.getTemplate("test1.ftl"); //数据模型 Map<String,Object> map = new HashMap<>(); map.put("name","高級程序员"); //静态化 String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map); //静态化内容 System.out.println(content); InputStream inputStream = IOUtils.toInputStream(content); //输出文件 FileOutputStream fileOutputStream = new FileOutputStream(new File("d:/test1.html")); int copy = IOUtils.copy(inputStream, fileOutputStream); }1.3.3.2 使用模板字符串静态化//基于模板字符串生成静态化文件 @Test public void testGenerateHtmlByString() throws IOException, TemplateException { //创建配置类 Configuration configuration=new Configuration(Configuration.getVersion()); //模板内容,这里测试时使用简单的字符串作为模板 String templateString="" + "<html>\n" + " <head></head>\n" + " <body>\n" + " 名称:${name}\n" + " </body>\n" + "</html>"; //模板加载器 StringTemplateLoader stringTemplateLoader = new StringTemplateLoader(); stringTemplateLoader.putTemplate("template",templateString); configuration.setTemplateLoader(stringTemplateLoader); //得到模板 Template template = configuration.getTemplate("template","utf‐8"); //数据模型 Map<String,Object> map = new HashMap<>(); map.put("name","高級程序员"); //静态化 String content = FreeMarkerTemplateUtils.processTemplateIntoString(template, map); //静态化内容 System.out.println(content); InputStream inputStream = IOUtils.toInputStream(content); //输出文件 FileOutputStream fileOutputStream = new FileOutputStream(new File("d:/test1.html")); IOUtils.copy(inputStream, fileOutputStream); } 
  • [技术干货] webpack入门
    webpack入门使用vue.js开发大型应用需要使用webpack打包工具,本节研究webpack的使用方法。1.3.1 webpack介绍 Webpack 是一个前端资源的打包工具,它可以将js、image、css等资源当成一个模块进行打包。从图中我们可以看出,Webpack 可以将js、css、png等多种静态资源 进行打包,使用webpack有什么好处呢?1 、模块化开发程序员在开发时可以分模块创建不同的js、 css等小文件方便开发,最后使用webpack将这些小文件打包成一个文件,减少了http的请求次数。webpack可以实现按需打包,为了避免出现打包文件过大可以打包成多个文件。2 、 编译typescript、ES6等高级js语法随着前端技术的强大,开发中可以使用javascript的很多高级版本,比如:typescript、ES6等,方便开发, webpack可以将打包文件转换成浏览器可识别的js语法。3 、CSS预编译webpack允许在开发中使用Sass 和 Less等原生CSS的扩展技术,通过sass-loader、less-loader将Sass 和 Less的 语法编译成浏览器可识别的css语法。webpack的缺点:1 、配置有些繁琐2 、文档不丰富1.3.2 安装webpack1.3.2.1 安装Node.jswebpack基于node.js运行,首先需要安装node.js。  为什么会有node.js?传统意义上的 JavaScript 运行在浏览器上,Chrome 使用的 JavaScript 引擎是 V8,Node.js 是一个运行在服务端的框架,它的底层就使用了 V8 引擎,这样就可以使用javascript去编写一些服务端的程序,这样也就实现了用javaScript去开发 Apache + PHP 以及 Java Servlet所开发的服务端功能,这样做的好处就是前端和后端都采用javascript,即开发一份js程序即可以运行在前端也可以运行的服务端,这样比一个应用使用多种语言在开发效率上要高,不过node.js属于新兴产品,一些公司也在尝试使用node.js完成一些业务领域,node.js基于V 8 引擎,基于事件驱动机制,在特定领域性能出色,比如用node.js实现消息推送、状态监控等的业务功能非常合适。下边我们去安装Node.js:1 、下载对应你系统的Node.js版本:https://nodejs.org/en/download/  推荐下载LTS版本,本教程安装 9 .4.0。2 、选安装目录进行安装默认即可安装完成检查PATH环境变量是否设置了node.js的路径。3 、测试在命令提示符下输入命令node ‐v会显示当前node的版本1 .3.2.2 安装NPM1 、自动安装NPMnpm全称Node Package Manager,他是node包管理和分发的工具,使用NPM可以对应用的依赖进行管理,NPM的功能和服务端项目构建工具maven差不多,我们通过npm 可以很方便地下载js库,打包js文件。node.js已经集成了npm工具,在命令提示符输入 npm -v 可查看当前npm版本  2 、设置包路径包路径就是npm从远程下载的js包所存放的路径。使用 npm config ls 查询NPM管理包路径(NPM下载的依赖包所存放的路径)  NPM默认的管理包路径在C:/用户/[用户名]/AppData/Roming/npm/node_meodules,为了方便对依赖包管理,我 们将管理包的路径设置在单独的地方,本教程将安装目录设置在node.js的目录下,创建npm_modules和 npm_cache,执行下边的命令:本教程安装node.js在D:\Program Files\nodejs下所以执行命令如下:npm config set prefix "C:\Program Files\nodejs\npm_modules"npm config set prefix "D:\nodejs\npm_modules" (更改本地仓库的位置)npm config set cache "c:\Program Files\nodejs\npm_cache"npm config set cache "D:\nodejs\npm_cache" (更改本地仓库的缓存位置)此时再使用 npm config ls 查询NPM管理包路径发现路径已更改  npm config set registry http://registry.npm.taobao.org 配置到此为止结束。3 、安装cnpmnpm默认会去国外的镜像去下载js包,在开发中通常我们使用国内镜像,这里我们使用淘宝镜像下边我们来安装cnpm:有时我们使用npm下载资源会很慢,所以我们可以安装一个cnmp(淘宝镜像)来加快下载速度。输入命令,进行全局安装淘宝镜像。npm install -g cnpm --registry=http://registry.npm.taobao.org安装后,我们可以使用以下命令来查看cnpm的版本cnpm -v  nrm ls 查看镜像已经指向taobao  使nrm use XXX切换 镜像如果nrm没有安装则需要进行全局安装:cnpm install -g nrm4 、非连网环境安装cnpm从本小节第 3 步开始就需要连网下载npm包,如果你的环境不能连网在老师的资料文件下有已经下载好的webpack相关包,下边是安装方法。1 )配置环境变量NODE_HOME = D:\Program Files\nodejs (node.js安装目录)在PATH变量中添加:%NODE_HOME%;%NODE_HOME%\npm_modules;2 )找到npm包路径根据上边的安装说明npm包路径被设置到了node.js安装目录下的npm_modules目录。可以使用npm config ls查看。拷贝课程资料中的 npm_modules.zip到node.js安装目录,并解压npm_modules.zip覆盖本目录下的 npm_modules文件夹。3 )完成上边步骤测试cnpm -v1.3.2.3 安装webpack1 、连网安装webpack安装分为本地安装和全局安装:本地安装:仅将webpack安装在当前项目的node_modules目录中,仅对当前项目有效。全局安装:将webpack安装在本机,对所有项目有效,全局安装会锁定一个webpack版本,该版本可能不适用某个项目。全局安装需要添加 -g 参数。进入webpacktest测试目录目录,运行:1 )本地安装:只在我的项目中使用webpack,需要进行本地安装,因为项目和项目所用的webpack的版本不一样。本地安装就会将webpack的js包下载到项目下的npm_modeuls目录下。在门户目录下创建webpack测试目录webpacktest01:npm install --save-dev webpack 或 cnpm install --save-dev webpacknpm install --save-dev webpack-cli (4.0以后的版本需要安装webpack-cli)2 )全局安装加-g,如下:全局安装就将webpack的js包下载到npm的包路径下。npm install webpack -g 或 cnpm install webpack -g3 )安装webpack指定的版本:本教程使用webpack3.6.0,安装webpack3.6.0:进入webpacktest测试目录,运行:cnpm install --save-dev webpack@3.6.全局安装:npm install webpack@3.6.0 -g或 cnpm install webpack@3.6.0 -g2 、非连网安装参考上边 “非连网环境安装cnpm”描述,将课程资料中的 npm_modules.zip到node.js安装目录,并解压 npm_modules.zip覆盖本目录下的npm_modules文件夹。说明:已执行 “非连网环境安装cnpm”下的操作不用重复执行。测试:在cmd状态输入webpack,出现如下提示说明 webpack安装成功 总结Webpack 是基于 Node.js 的现代前端静态模块打包器,核心功能是将 JS、CSS、图片等多种资源视作模块,通过打包优化项目结构与性能,是 Vue 等框架开发大型应用的核心工具。其核心优势显著:支持模块化开发,可将代码拆分为小模块便于维护,打包后减少 HTTP 请求次数,还能按需拆分避免文件过大;通过 loader 机制编译 ES6、TypeScript 等高级语法及 Sass、Less 等 CSS 预编译语言,适配浏览器兼容;搭配插件生态可实现热模块替换等功能,提升开发效率。安装需先部署 Node.js(含 npm 包管理工具),可配置淘宝镜像(cnpm)加速下载,支持全局与本地两种安装方式,本地安装更适配多项目版本差异。虽存在配置繁琐、早期文档不足的缺点,但凭借强大的资源处理与优化能力,仍是前端工程化开发的主流工具。
  • 如何防止webpack打包被逆向?
    不少开发者认为:webpack打包后的js代码,看起来很混乱,似乎源码得到了保护。其实不然,因为webpack只是将多个文件合并到了一起,并没有多少保护代码的功能。比如下面这个例子,该网站的js文件是经webpack打包编译后生成的:只需将上述显示的文件下载,很简单便可以还原出原始工程文件和代码(如下图所示,vue、js、json等等):轻松便得到了源码,js中的功能逻辑、实现方法,一目了然,连注释都在:可见webpack打包,不能保护js代码,不具备安全防护效果。在我们的项目开发过程中,为了避免上述问题。在发布前,很建议用专业的js加密工具,对js代码进行混淆加密,比如JShaman、JsJiami.online等。然后再发布。混淆加密后的js代码,即使泄露,也可避免被人轻松分析、避免重要信息泄露、避免被二次开发利用。
  • [技术干货] Webpack部署本地服务器的方法【转】
    Webpack部署本地服务器目的完成自动编译常用方式: webpack-dev-serverwebpack-dev-server 是一个用于开发环境的 Web 服务器,它集成了 Webpack,并提供了实时重新加载和热替换等功能。以下是一个简单的 webpack-dev-server 配置和使用示例:1.首先,确保已经安装了 webpack, webpack-cli 和 webpack-dev-server。如果没有安装,可以使用以下命令进行安装:1npm install --save-dev webpack webpack-cli webpack-dev-server -D   // 开发环境2.在项目根目录下创建一个名为 webpack.config.js 的文件,用于存放 Webpack 配置信息:1234567891011121314151617const path = require('path');module.exports = {  entry: './src/index.js',  output: {    filename: 'main.js',    path: path.resolve(__dirname, 'dist'),  },  devServer: {    contentBase: path.join(__dirname, 'dist'),    // 是否为静态文件开启 gzip compression 默认是false    compress: true,    port: 9000,    // open 是否打开浏览器, 默认是 false     open: true,    hot: true,  },};这个配置文件定义了入口文件为 src/index.js,输出文件为 dist/main.js,并配置了 webpack-dev-server 的相关参数。3.在项目的 package.json 文件中添加一个启动脚本:12345{  "scripts": {    "serve": "webpack serve"  }}现在,可以通过运行 npm run serve 命令来启动 webpack-dev-server。服务器将在端口 9000 上启动,并在默认浏览器中打开 http://localhost:9000。当你对 src/index.js 文件进行更改时,服务器将自动重新加载和热替换。 认识模块热替换(HMR)什么是 HMRp HMR的全称是Hot Module Replacement,翻译为模块热替换;p 模块热替换是指在 应用程序运行过程中,替换、添加、删除模块,而无需重新刷新整个页面;HMR 通过如下几种方式, 来提高开发的速度p 不重新加载整个页面,这样可以保留某些应用程序的状态不丢失;p 只更新需要变化的内容,节省开发的时间;p 修改了css、js源代码,会立即在浏览器更新,相当于直接在浏览器的devtools中直接修改样式;如何使用 HMR默认情况下,webpack-dev-server已经支持HMR,我们只需要开启即可**(默认已经开启);**在不开启HMR的情况下,当我们修改了源代码之后,整个页面会自动刷新,使用的是live reloading;host 配置host设置主机地址:默认值是localhost;如果希望其他地方也可以访问,可以设置为 0.0.0.0;port、open、compressport设置监听的端口,默认情况下是8080open是否打开浏览器:默认值是false,设置为true会打开浏览器;也可以设置为类似于 Google Chrome等值;compress是否为静态文件开启gzip compression:默认值是false,可以设置为true;
  • [技术干货] 一文入门Webpack文件指纹
    什么是文件指纹文件指纹是文件打包后输出的文件名的后缀,通常用来做一些文件的版本管理文件指纹的作用• 用作版本管理时,如果一个项目需要发布,只需要发布修改过的文件指纹;• 对于没有修改过的文件,用户在访问的时候,依旧可以使用浏览器缓存好的,无需二次加载,加速页面访问。文件指纹策略• Hash和整个项目的构建相关,只要项目文件有修改,整个项目构建的hash值就会更改,并且全部文件都共用相同的hash值• Chunkhash和webpack打包的chunk有关,不同的entyr会生成不同的Chunkhash值(一个页面的值改变了并不会影响另一个页面,js文件一般采用此方法),chunkhash和hash不一样,它根据不同的入口文件(Entry)进行依赖文件解析、构建对应的chunk,生成对应的哈希值。我们在生产环境里把一些公共库和程序入口文件区分开,单独打包构建,接着我们采用chunkhash的方式生成哈希值,那么只要我们不改动公共库的代码,就可以保证其哈希值不会受影响。• Contenthash根据文件内容来定义hash,文件内容不变,则contenthash不变(css文件一般采用此方法)。比如文件index.css被index.js引用了,所以共用相同的chunkhash值。但是这样子有个问题,如果index.js更改了代码,css文件就算内容没有任何改变,由于是该模块发生了改变,导致css文件会重复构建。这个时候,我们可以使用extra-text-webpack-plugin里的contenthash值,保证即使css文件所处的模块里就算其他文件内容改变,只要css文件内容不变,那么不会重复构建。hash一般是结合CDN缓存来使用,通过webpack构建之后,生成对应文件名自动带上对应的MD5值。如果文件内容改变的话,那么对应文件哈希值也会改变,对应的HTML引用的URL地址也会改变,触发CDN服务器从源服务器上拉取对应数据,进而更新本地缓存。但是在实际使用的时候,这几种hash计算还是有一定区别。占位符介绍占位符名称定义[ext]资源后缀名[name]文件名称[path]文件的相对路径[folder]文件所在的文件夹[contenthash]文件的内容hash,默认是md5生成[hash]文件的内容hash,默认是md5生成[emoji]一个随机的指代文件内容的emoji文件指纹的设置根据不同的文件类型一般选择不同的文件指纹策略,通常情况下:• JS文件采用[chunkhash]文件指纹策略• CSS文件采用[contenthash]文件指纹策略• JS文件采用[hash]文件指纹策略下面我们来介绍下几种用法JS文件指纹设置设置output的filename,使用[chunkhash],chunkhash没办法和热更新一起使用的,不能与HotModuleReplacementPlugin这个插件一起使用,所以我们只在生产环境写。1234output: {                               //打包输出文件        path: path.join(__dirname, 'dist'),        filename: '[name]_[chunkhash:8].js' //chunkhash指纹策略,截取前面8个字符    }图片文件指纹设置设置file-loader的name,使用[hash]。12345678910111213module: {        rules: [            {                test: /.(png|jpg|gif|jpeg)$/,                use: {                    loader: "url-loader",                    options: {                        name: '[name]_[hash:8].[ext]',                        limit: 10240 //不超过10K时,将其转化为base64                    }                }            },    },CSS文件指纹设置CSS文件指纹策略比较特殊,我们需要用到MiniCssExtractPlugin,设置MiniCssExtractPlugin 的 filename,使用[contenthash]。正常情况下,如果我们使用了style-loader和css-loader的话,那么这个css会由style-loader将css插入到style里面,并且放到head头部,此时并没有一个独立的css文件,因此,我们通常会采用MiniCssExtractPlugin,通过这个插件把这个style-loader的css提取成一个独立的文件,所以,对于这个css的文件指纹,我们会设置在这个MiniCssExtractPlugin里面,给它设置一个filename,并且给它设置一个[contenthash]。注意:MiniCssExtractPlugin这个插件没办法与style-loader一起使用,因为它们之间的功能是互斥的,所以需要将style-loader换成MiniCssExtractPlugin.loader。设置步骤首先安装MiniCssExtractPlugin1npm i -D mini-css-extract-plugin配置webpack.config.js123456789const MiniCssExtractPlugin = require('mini-css-extract-plugin');......module.exports = {        plugins: [        new MiniCssExtractPlugin({            filename: '[name][contenthash:8].css'        })    ],}文件指纹项目应用将webpack.config.js文件更名为webpack.dev.js并将内部的mode修改为development,再复制一份文件,更名为webpack.prod.js将mode修改为production。然后需要修改配置文件package.json区分production和development123456"scripts": {    "test": "echo \"Error: no test specified\" && exit 1",    "build": "webpack --config webpack.prod.js",    "watch": "webpack --watch --progress",    "dev": "webpack-dev-server -config webpack.dev.js --open"  }完成上述步骤,我们在项目中就可以根据生产环境和开发环境不同,配置不同的文件指纹。原文链接:https://blog.csdn.net/huangbiao86/article/details/123121470
  • [技术干货] 想了解Webpack,看这篇就够了
    1. 摘要Webpack是一种前端资源构建工具,一个静态模块打包器。在Webpack看来,前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理,当Webpack处理应用程序时,它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源。Webpack打包流程图如图1-1所示。图1-1 Webpack打包流程图2. Webpack五个核心概念2.1 Entry入口(Entry)指示Webpack以哪个文件作为入口起点分析构建内部依赖图并进行打包。2.2 Output输出(Output)指示Webpack打包后的资源bundles输出到哪里去,以及如何命名。2.3 LoaderLoader让Webpack能够去处理那些非JavaScript语言的文件,Webpack本身只能理解JavaScript。2.4 Plugins插件(Plugins)可以用于执行范围更广的任务,插件的范围包括从打包和压缩,一直到重新定义环境中的变量等。2.5 Mode模式(Mode)指示Webpack使用相应模式的配置。分为development和production两种模式,下面分别进行简述。development: 开发模式,能让代码本地运行的环境,会将process.env.NODE_ENV的值设为development,同时启用NamedChunksPlugin和NamedModulesPlugin插件;production: 生产模式,能让代码优化运行的环境,会将process.env.NODE_ENV的值设为production,同时启用FlagDependencyUsagePlugin、FlagIncludedChunksPlugin、ModuleConcatenationPlugin、NoEmitreplaceStringsPlugin、OccurrenceOrderPlugin、SideEffectsFlagPlugin和UglifyJsPlugin插件。3. Wbepack配置3.1 webpack.config.js文件webpack.config.js是webpack的配置文件,用来指示webpack工作,运行webpack指令时,会加载里面的配置,所有构建工具都是基于nodejs平台运行的,默认采用commonjs模块化。webpack.config.js基础配置如图3-1所示。图3-1 webpack.config.js基础配置3.2 devServer配置开发服务器(devServer)用来实现自动化(自动编译、自动打开浏览器、自动刷新浏览器),只会在内存中编译打包,不会有任何文件输出,本地安装webpack-dev-server后,通过npx webpack-dev-server命令启动devServer,核心代码如图3-2所示。图3-2 devServer配置核心代码3.3 打包html/样式/图片/其它资源打包不同的资源会使用不同的loader和插件,打包html/样式/图片/其它资源的流程如下所述。3.3.1 打包html资源1.下载html-webpack-plugin插件;2.引入html-webpack-plugin插件;3.使用html-webpack-plugin插件,并进行相应配置。3.3.2 打包样式资源不同的样式文件需要配置不同的loader1.下载loader;2.配置loader,css样式文件使用css-loader和style-loader,less文件使用less-loader、css-loader和style-loader。其中css-loader的作用是将css文件变成commonjs模块加载到js文件中,style-loader的作用是创建style标签,将js中的样式资源插入进去,添加到head中生效。3.3.3 打包图片资源1.下载url-loader,file-loader2.配置loader3.3.4 打包其它资源1.下载file-loader2. 配置loader,配置该loader作用于不为html/css/less/js的其他文件3.4 提取css成单独文件/css兼容性处理/压缩css3.4.1 提取css成单独文件样式文件打包后会默认和js文件一起输出,可以通过插件将打包后的css文件单独输出,流程如下所述。1.下载mini-css-extract-plugin插件2.引用该插件3.配置3.4.2 css兼容性处理1.下载postcss-loader和postcss-preset-env2.在package.json中browsetslist属性中分别对开发环境和生产环境进行兼容性配置,设置支持样式的浏览器版本3.通过postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式。3.4.3 压缩css1.下载optimize-css-assets-webpack-plugin插件2.引用该插件3.使用该插件3.5 js语法检查eslint/js兼容性处理/js压缩3.5.1 js语法检查eslint1.下载eslint-loader和eslint2.在package.json中的eslintConfig中进行配置3.配置eslint-loader,其中只需检测js文件并要排除第三方库,只检测自己写的源代码,同时可在options配置中设置fix:true,自动修复eslint的错误。3.5.2 js兼容性处理1.下载babel-loader、@babel/core、@babel/preset-env,通过@babel/preset-env做基本的js兼容性处理,然后通过corejs做前面无法实现的兼容性处理,并实现按需加载2. 配置loaderjs兼容性处理核心代码如图3-3所示图3-3 js兼容性处理核心代码3.5.3 js压缩mode设置为production生产环境时会自动压缩js代码。4. webpack性能优化可以从开发环境和生产环境分别对webpack进行性能优化。其中开发环境主要考虑从打包构建速度和代码调试两个方面进行优化,生产环境主要考虑从打包构建速度和代码运行性能这两个方面进行优化。下面简单介绍下开发环境上通过HMR提升构建速度。4.1 HMRHMR(热模块替换),作用是一个模块发生变化后,只会更新打包这一个模块而不是所有模块,通过在devServer中设置hot:true属性启动HMR功能。其中对于样式文件,可以使用HMR功能,因为style-loader内部实现了;对于js文件,默认不能使用HMR功能,解决方法:修改入口文件js代码,添加支持HMR功能的代码,另外HMR只能处理非入口js文件的其他文件,对入口文件并不能生效,因为一旦入口文件更新,入口文件引入的其他文件一定会被重新加载;对于html文件,默认不能使用HMR功能,同时会导致html文件不能热更新,解决方法:修改entry入口文件,将html文件引入,只能解决html文件不能热更新的问题。js文件支持HMR功能的核心代码如图4-1所示。图4-1 js文件支持HMR功能核心代码4.2 HMR效果在入口index.js文件中引入print.js文件,运行npx webpack-devserver后,页面如图4-2所示。4-2 初始页面修改print.js文件后,只会重新加载print.js文件,而不会重新加载index.js文件,HMR效果如图4-3所示。4-3 HMR效果图
  • [技术干货] 初识Webpack
    1. 摘要Webpack是一种前端资源构建工具,一个静态模块打包器。在Webpack看来,前端的所有资源文件(js/json/css/img/less/…)都会作为模块处理,当Webpack处理应用程序时,它将根据模块的依赖关系进行静态分析,打包生成对应的静态资源。Webpack打包流程图如图1-1所示。图1-1 Webpack打包流程图2. Webpack五个核心概念2.1 Entry入口(Entry)指示Webpack以哪个文件作为入口起点分析构建内部依赖图并进行打包。2.2 Output输出(Output)指示Webpack打包后的资源bundles输出到哪里去,以及如何命名。2.3 LoaderLoader让Webpack能够去处理那些非JavaScript语言的文件,Webpack本身只能理解JavaScript。2.4 Plugins插件(Plugins)可以用于执行范围更广的任务,插件的范围包括从打包和压缩,一直到重新定义环境中的变量等。2.5 Mode模式(Mode)指示Webpack使用相应模式的配置。分为development和production两种模式,下面分别进行简述。development: 开发模式,能让代码本地运行的环境,会将process.env.NODE_ENV的值设为development,同时启用NamedChunksPlugin和NamedModulesPlugin插件;production: 生产模式,能让代码优化运行的环境,会将process.env.NODE_ENV的值设为production,同时启用FlagDependencyUsagePlugin、FlagIncludedChunksPlugin、ModuleConcatenationPlugin、NoEmitOnErrorsPlugin、OccurrenceOrderPlugin、SideEffectsFlagPlugin和UglifyJsPlugin插件。3. Wbepack配置3.1 webpack.config.js文件webpack.config.js是webpack的配置文件,用来指示webpack工作,运行webpack指令时,会加载里面的配置,所有构建工具都是基于nodejs平台运行的,默认采用commonjs模块化。webpack.config.js基础配置如图3-1所示。图3-1 webpack.config.js基础配置3.2 devServer配置开发服务器(devServer)用来实现自动化(自动编译、自动打开浏览器、自动刷新浏览器),只会在内存中编译打包,不会有任何文件输出,本地安装webpack-dev-server后,通过npx webpack-dev-server命令启动devServer,核心代码如图3-2所示。图3-2 devServer配置核心代码3.3 打包html/样式/图片/其它资源打包不同的资源会使用不同的loader和插件,打包html/样式/图片/其它资源的流程如下所述。3.3.1 打包html资源1.下载html-webpack-plugin插件;2.引入html-webpack-plugin插件;3.使用html-webpack-plugin插件,并进行相应配置。3.3.2 打包样式资源不同的样式文件需要配置不同的loader1.下载loader;2.配置loader,css样式文件使用css-loader和style-loader,less文件使用less-loader、css-loader和style-loader。其中css-loader的作用是将css文件变成commonjs模块加载到js文件中,style-loader的作用是创建style标签,将js中的样式资源插入进去,添加到head中生效。3.3.3 打包图片资源1.下载url-loader,file-loader2.配置loader3.3.4 打包其它资源1.下载file-loader2. 配置loader,配置该loader作用于不为html/css/less/js的其他文件3.4 提取css成单独文件/css兼容性处理/压缩css3.4.1  提取css成单独文件样式文件打包后会默认和js文件一起输出,可以通过插件将打包后的css文件单独输出,流程如下所述。1.下载mini-css-extract-plugin插件2.引用该插件3.配置3.4.2 css兼容性处理1.下载postcss-loader和postcss-preset-env2.在package.json中browsetslist属性中分别对开发环境和生产环境进行兼容性配置,设置支持样式的浏览器版本3.通过postcss找到package.json中browserslist里面的配置,通过配置加载指定的css兼容性样式。3.4.3 压缩css1.下载optimize-css-assets-webpack-plugin插件2.引用该插件3.使用该插件3.5 js语法检查eslint/js兼容性处理/js压缩3.5.1 js语法检查eslint1.下载eslint-loader和eslint2.在package.json中的eslintConfig中进行配置3.配置eslint-loader,其中只需检测js文件并要排除第三方库,只检测自己写的源代码,同时可在options配置中设置fix:true,自动修复eslint的错误。3.5.2 js兼容性处理    1.下载babel-loader、@babel/core、@babel/preset-env,通过@babel/preset-env做基本的js兼容性处理,然后通过corejs做前面无法实现的兼容性处理,并实现按需加载    2. 配置loaderjs兼容性处理核心代码如图3-3所示图3-3 js兼容性处理核心代码3.5.3 js压缩mode设置为production生产环境时会自动压缩js代码。4. webpack性能优化可以从开发环境和生产环境分别对webpack进行性能优化。其中开发环境主要考虑从打包构建速度和代码调试两个方面进行优化,生产环境主要考虑从打包构建速度和代码运行性能这两个方面进行优化。下面简单介绍下开发环境上通过HMR提升构建速度。4.1 HMR    HMR(热模块替换),作用是一个模块发生变化后,只会更新打包这一个模块而不是所有模块,通过在devServer中设置hot:true属性启动HMR功能。其中对于样式文件,可以使用HMR功能,因为style-loader内部实现了;对于js文件,默认不能使用HMR功能,解决方法:修改入口文件js代码,添加支持HMR功能的代码,另外HMR只能处理非入口js文件的其他文件,对入口文件并不能生效,因为一旦入口文件更新,入口文件引入的其他文件一定会被重新加载;对于html文件,默认不能使用HMR功能,同时会导致html文件不能热更新,解决方法:修改entry入口文件,将html文件引入,只能解决html文件不能热更新的问题。js文件支持HMR功能的核心代码如图4-1所示。图4-1 js文件支持HMR功能核心代码4.2  HMR效果在入口index.js文件中引入print.js文件,运行npx webpack-devserver后,页面如图4-2所示。4-2 初始页面修改print.js文件后,只会重新加载print.js文件,而不会重新加载index.js文件,HMR效果如图4-3所示。4-3 HMR效果图