一、概要

1.1、前端工程化

随着前端的不断发展与壮大,前端变得越来越复杂,组件化、模块化、工程化、自动化成了前端发展中不可或缺的一部分,具体到前端工程化,面临的问题是如何提高编码->测试->维护阶段的生产效率。

前端工程化是使用软件工程的技术和方法来进行前端项目的开发、维护和管理。

前端工程化是依据业务特点,将前端开发的规范、流程、技术、工具、经验等形成规范并建立成一种标准的体系。

现在的项目可能会不停的迭代,发布就成了日常开发的一部分,前端不仅要保证功能还要保证性能,传统的一次次的发布效率会非常低,前端工程化一般都有会借助一些工具。

实现前端工程化的目的简单来说就是通过流程规范、自动化工具来提升前端的开发效率、性能、质量、多人协作能力以及开发体验,建立前端工程化是各个团队必经的成长过程。

1.1.1、前端工程化的任务

前端不仅要保证功能还要考虑性能,要减少http请求数量、压缩、合并、预处理、规范代码、清理、打包、转换等工作。

前端大部分情况下源代码无法直接运行,必须通过转换后才可以正常运行。构建就是做这件事情,把源代码转换成发布到线上的可执行 JavaScrip、CSS、HTML 代码,包括如下内容。

(1)、代码转换:TypeScript 编译成 JavaScript、SCSS 编译成 CSS 等。

(2)、文件优化:压缩 JavaScript、CSS、HTML 代码,压缩合并图片等。

(3)、代码分割:提取多个页面的公共代码、提取首屏不需要执行部分的代码让其异步加载。

(4)、模块合并:在采用模块化的项目里会有很多个模块和文件,需要构建功能把模块分类合并成一个文件。

(5)、自动刷新:监听本地源代码的变化,自动重新构建、刷新浏览器。

(6)、代码校验:在代码被提交到仓库前需要校验代码是否符合规范,以及单元测试是否通过。

(7)、自动发布:更新完代码后,自动构建出线上发布代码并传输给发布系统。

构建其实是工程化、自动化思想在前端开发中的体现,把一系列流程用代码去实现,让代码自动化地执行这一系列复杂的流程。 构建给前端开发注入了更大的活力,解放了我们的生产力。

1.2、前端工程化工具

历史上先后出现一系列构建工具,它们各有其优缺点。由于前端工程师很熟悉 JavaScript ,Node.js 又可以胜任所有构建需求,所以大多数构建工具都是用 Node.js 开发的。

构建工具的主要功能就是实现自动化处理,例如对代码进行检查、预编译、合并、压缩;生成雪碧图、sourceMap、版本管理;运行单元测试、监控等,当然有的工具还提供模块化、组件化的开发流程功能。

 

如果把工具按类型分可以分为这三类:

(一)、基于任务运行的工具:Grunt、Gulp

它们会自动执行指定的任务,就像流水线,把资源放上去然后通过不同插件进行加工,它们包含活跃的社区,丰富的插件,能方便的打造各种工作流。

(二)、基于模块化打包的工具:Browserify、Webpack、rollup.js

有过 Node.js 开发经历的应该对模块很熟悉,需要引用组件直接一个 require 就 OK,这类工具就是这个模式,还可以实现按需加载、异步加载模块。

(三)、整合型工具:Yeoman、FIS、jdf、Athena、cooking、weflow

使用了多种技术栈实现的脚手架工具,好处是即开即用,缺点就是它们约束了技术选型,并且学习成本相对较高。

1.2.1、Grunt

Grunt([ɡrʌnt]作呼噜声) 生态系统非常庞大,并且一直在增长。由于拥有数量庞大的插件可供选择,因此,你可以利用 Grunt 自动完成许多事,并且花费很少的代价。如果找不到你所需要的插件,那就自己动手创造一个 Grunt 插件,然后将其发布到 npm 上吧。

官网:https://gruntjs.com/

GitHub:https://github.com/gruntjs/

中文网:https://www.gruntjs.net/

对于需要反复重复的任务,例如压缩(minification)、编译、单元测试、linting等,自动化工具可以减轻你的劳动,简化你的工作。当你在 Gruntfile 文件正确配置好了任务,任务运行器就会自动帮你或你的小组完成大部分无聊的工作。

Grunt 是老牌的构建工具,特点是配置驱动,你需要做的就是了解各种插件的功能,然后把配置整合到 Gruntfile.js 中,下面是配置例子:

复制代码
module.exports = function(grunt) {grunt.initConfig({jshint: {files: ['Gruntfile.js', 'src/**/*.js', 'test/**/*.js'],options: {globals: {jQuery: true}}},watch: {files: ['<%= jshint.files %>'],tasks: ['jshint']}});grunt.loadNpmTasks('grunt-contrib-jshint');grunt.loadNpmTasks('grunt-contrib-watch');grunt.registerTask('default', ['jshint']);
};
复制代码

Grunt 缺点也是配置驱动,当任务非常多的情况下,试图用配置完成所有事简直就是个灾难;再就是它的 I/O 操作也是个弊病,它的每一次任务都需要从磁盘中读取文件,处理完后再写入到磁盘,例如:我想对多个 less 进行预编译、压缩操作,那么 Grunt 的操作就是:

读取 less 文件 -> 编译成 css -> 存储到磁盘 -> 读取 css -> 压缩处理 -> 存储到磁盘

这样一来当资源文件较多,任务较复杂的时候性能就是个问题了。

1.2.2、Gulp

Gulp(ɡʌlp狼吞虎咽地吃,吞咽)是一个基于流的自动化构建工具。 除了可以管理和执行任务,还支持监听文件、读写文件。

中文网:https://www.gulpjs.com.cn/

官网:https://gulpjs.com/

特点:

易于使用:通过代码优于配置的策略,Gulp 让简单的任务简单,复杂的任务可管理。

构建快速:利用 Node.js 流的威力,你可以快速构建项目并减少频繁的 IO 操作。

插件高质:Gulp 严格的插件指南确保插件如你期望的那样简洁高质得工作。

易于学习:通过最少的 API,掌握 Gulp 不太费力,构建工作尽在掌握:如同一系列流管道。

Gulp 被设计得非常简单,只通过下面5种个方法就可以胜任几乎所有构建场景:

通过 gulp.task 注册一个任务;

通过 gulp.run 执行任务;

通过 gulp.watch 监听文件变化;

通过 gulp.src 读取文件;

通过 gulp.dest 写文件。

Gulp 的最大特点是引入了流的概念,同时提供了一系列常用的插件去处理流,流可以在插件之间传递

Gulp 特点是代码驱动,写任务就和写普通的 Node.js 代码一样:

复制代码
var gulp = require('gulp');
var pug = require('gulp-pug');
var less = require('gulp-less');
var minifyCSS = require('gulp-csso');gulp.task('html', function(){return gulp.src('client/templates/*.pug').pipe(pug()).pipe(gulp.dest('build/html'))
});gulp.task('css', function(){return gulp.src('client/templates/*.less').pipe(less()).pipe(minifyCSS()).pipe(gulp.dest('build/css'))
});gulp.task('default', [ 'html', 'css' ]);
复制代码

再一个对文件读取是流式操作(Stream),也就是说一次 I/O 可以处理多个任务,还是 less 的例子,Gulp 的流程就是:

读取 less 文件 -> 编译成 css -> 压缩处理 -> 存储到磁盘

Gulp 作为任务类型的工具没有明显的缺点,唯一的问题可能就是完成相同的任务它需要写的代码更多一些,所以除非是项目有历史包袱(原有项目就是基于 Grunt 构建)在 Grunt 与 Gulp 对比看来还是比较推荐 Gulp!

适用场景:

通过上面的介绍可以看出它们侧重对整个过程的控制管理,实现简单、对架构无要求、不改变开发模式,所以非常适合前端、小型、需要快速启动的项目。

1.2.3、Yeoman

Yeoman([ˈjoʊmən]自耕农,自由民; 义勇骑兵队成员,young+man)的目的不仅是要为新项目建立工作流,同时还是为了解决前端开发所面临的诸多严重问题,例如零散的依赖关系。
Yeoman是Google的团队和外部贡献者团队合作开发的,他的目标是通过Grunt(一个用于开发任务自动化的命令行工具)和Bower(一个HTML、CSS、Javascript和图片等前端资源的包管理器)的包装为开发者创建一个易用的工作流。

Yeoman是一个强健的脚手架与构建工具,库,及工作流程的组合,帮你网页开发者快速创建出漂亮而且引人入胜的网页程序,Yeoman帮助我们创建项目,提供更好的工具来使我们的项目更多样化。

Yeoman提供generator系统,一个generator是一个插件,在我们在一个完整的项目上使用‘yo’命令时,会运行该generator。通过这些官方的Generators,推出了Yeoman工作流,工作流是一个健壮、有自己特色的客户端堆栈,包含能快速构建漂亮的网络应用的工具和框架。Yeoman提供了负责开始项目开发的一切,没有任何让人头痛的手动配置。

Yeoman主要提供了三个工具:脚手架(yo),构建工具(grunt),包管理器(bower)。这三个工具是分别独立开发的,但是需要配合使用,来实现我们更高效的工作流模式。

小结:

在 Npm Script 和 Grunt 时代,Web 开发要做的事情变多,流程复杂,自动化思想被引入,用于简化流程;

在 Gulp 时代开始出现一些新语言用于提高开发效率,流式处理思想的出现是为了简化文件转换的流程,例如将 ES6 转换成 ES5。

在 Webpack 时代由于单页应用的流行,一个网页的功能和实现代码变得庞大,Web 开发向模块化改进。

这些构建工具都有各自的定位和专注点,它们之间既可以单独地完成任务,也可以相互搭配起来弥补各自的不足。 在了解这些常见的构建工具后,你需要根据自己的需求去判断应该如何选择和搭配它们才能更好地完成自己的需求。

经过多年的发展, Webpack 已经成为构建工具中的首选,原因是:

大多数团队在开发新项目时会采用紧跟时代的技术,这些技术几乎都会采用“模块化+新语言+新框架”,Webpack 可以为这些新项目提供一站式的解决方案;

Webpack 有良好的生态链和维护团队,能提供良好的开发体验和保证质量;

Webpack 被全世界的大量 Web 开发者使用和验证,能找到各个层面所需的教程和经验分享。

1.3、WebPack

webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

Webpack 是一个打包模块化 JavaScript 的工具,在 Webpack 里一切文件皆模块,通过 Loader 转换文件,通过 Plugin 注入钩子,最后输出由多个模块组合成的文件。Webpack 专注于构建模块化项目。

其官网的首页图很形象的画出了 Webpack 是什么,如下:

一切文件:JavaScript、CSS、SCSS、图片、模板,在 Webpack 眼中都是一个个模块,这样的好处是能清晰的描述出各个模块之间的依赖关系,以方便 Webpack 对模块进行组合和打包。 经过 Webpack 的处理,最终会输出浏览器能使用的静态资源。

Webpack 具有很大的灵活性,能配置如何处理文件,大致使用如下:

复制代码
module.exports = {
// 所有模块的入口,Webpack 从入口开始递归解析出所有依赖的模块entry: './app.js',output: {
// 把入口所依赖的所有模块打包成一个文件 bundle.js 输出 filename: 'bundle.js'}
}
复制代码

1.3.1、Webpack的特点

把一切都视为模块:不管是 CSS、JS、Image 还是 HTML 都可以互相引用,通过定义 entry.js,对所有依赖的文件进行跟踪,将各个模块通过 loader 和 plugins 处理,然后打包在一起。

按需加载:打包过程中 Webpack 通过 Code Splitting 功能将文件分为多个 chunks,还可以将重复的部分单独提取出来作为 commonChunk,从而实现按需加载。

优点:

专注于处理模块化的项目,能做到开箱即用一步到位;

通过 Plugin 扩展,完整好用又不失灵活;

使用场景不仅限于 Web 开发;

社区庞大活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展;

良好的开发体验。

缺点:

Webpack的缺点是只能用于采用模块化开发的项目。

上手比较难、对于新手而言需要经历踩坑的过程。

对于Server 端渲染的多页应用有点力不从心。

小结:

Webpack 特别适合配合 React.js、Vue.js 构建单页面应用以及需要多人合作的大型项目,在规范流程都已约定好的情况下往往能极大的提升开发效率与开发体验。

1.3.2、资源

官网:https://webpack.js.org/

github:https://github.com/webpack/webpack

中文网:https://www.webpackjs.com/

深入浅出webpack电子书:http://webpack.wuhaolin.cn/

1.3.3、工作流程

Webpack 是通过配置来实现管理,与 Grunt 不同的是它包含的许多自动化的黑盒操作所以配置起来会简单很多(但遇到问题调试起来就很麻烦),一个典型的配置如下:

复制代码
module.exports = {//插件项plugins: [commonsPlugin],//页面入口文件配置entry: {index : './src/js/page/index.js'},//入口文件输出配置output: {path: 'dist/js/page',filename: '[name].js'},module: {//加载器配置loaders: [{ test: /\.css$/, loader: 'style-loader!css-loader' },{ test: /\.js$/, loader: 'jsx-loader?harmony' },{ test: /\.scss$/, loader: 'style!css!sass?sourceMap'},{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192'}]},//其它解决方案配置resolve: {root: '/Users/Bell/github/flux-example/src', //绝对路径extensions: ['', '.js', '.json', '.scss'],alias: {AppStore : 'js/stores/AppStores.js',ActionType : 'js/actions/ActionType.js',AppAction : 'js/actions/AppAction.js'}}
};
复制代码

 

1.3.4、搭建WebPack开发环境

(1)、安装NodeJS

在用 Webpack 执行构建任务时需要通过 webpack 可执行文件去启动构建任务,所以需要安装 webpack 可执行文件。 在安装 Webpack 前请确保你的系统安装了5.0.0及以上版本的 Node.js。

去https://nodejs.org/下载安装

设置国内npm的镜像

$ npm install -g cnpm --registry=https://registry.npm.taobao.org

使用时用cnpm代替npm

(2)、安装webpack

安装 Webpack 到全局

安装到全局后你可以在任何地方共用一个 Webpack 可执行文件,而不用各个项目重复安装,安装方式如下:

npm i -g webpack

cli:

所有cli参数:

webpack-cli 3.1.2Usage: webpack-cli [options]webpack-cli [options] --entry <entry> --output <output>webpack-cli [options] <entries...> --output <output>webpack-cli <command> [options]For more information, see https://webpack.js.org/api/cli/.Config options:--config               Path to the config file[string] [default: webpack.config.js or webpackfile.js]--config-register, -r  Preload one or more modules before loading the webpackconfiguration      [array] [default: module id or path]--config-name          Name of the config to use                      [string]--env                  Environment passed to the config, when it is a function--mode                 Enable production optimizations or development hints.[choices: "development", "production", "none"]Basic options:--context    The base directory (absolute path!) for resolving the `entry`option. If `output.pathinfo` is set, the included pathinfo isshortened to this directory.[string] [default: The current directory]--entry      The entry point(s) of the compilation.                   [string]--watch, -w  Enter watch mode, which rebuilds on file change.        [boolean]--debug      Switch loaders to debug mode                            [boolean]--devtool    A developer tool to enhance debugging.                   [string]-d           shortcut for --debug --devtool eval-cheap-module-source-map--output-pathinfo                                       [boolean]-p           shortcut for --optimize-minimize --defineprocess.env.NODE_ENV="production"                       [boolean]--progress   Print compilation progress in percentage                [boolean]Module options:--module-bind       Bind an extension to a loader                     [string]--module-bind-post  Bind an extension to a post loader                [string]--module-bind-pre   Bind an extension to a pre loader                 [string]Output options:--output, -o                  The output path and file for compilation assets--output-path                 The output directory as **absolute path**(required).[string] [default: The current directory]--output-filename             Specifies the name of each output file on disk.You must **not** specify an absolute path here!The `output.path` option determines the locationon disk the files are written to, filename isused solely for naming the individual files.[string] [default: [name].js]--output-chunk-filename       The filename of non-entry chunks as relativepath inside the `output.path` directory.[string] [default: filename with [id] instead of [name] or [id] prefixed]--output-source-map-filename  The filename of the SourceMaps for theJavaScript files. They are inside the`output.path` directory.                [string]--output-public-path          The `publicPath` specifies the public URLaddress of the output files when referenced in abrowser.                                [string]--output-jsonp-function       The JSONP function used by webpack for asyncloading of chunks.                      [string]--output-pathinfo             Include comments with information about themodules.                               [boolean]--output-library              Expose the exports of the entry point as library[string]--output-library-target       Type of library[string] [choices: "var", "assign", "this", "window", "self", "global","commonjs", "commonjs2", "commonjs-module", "amd", "umd", "umd2", "jsonp"]Advanced options:--records-input-path       Store compiler state to a json file.       [string]--records-output-path      Load compiler state from a json file.      [string]--records-path             Store/Load compiler state from/to a json file. Thiswill result in persistent ids of modules andchunks. An absolute path is expected. `recordsPath`is used for `recordsInputPath` and`recordsOutputPath` if they left undefined.[string]--define                   Define any free var in the bundle          [string]--target                   Environment to build for                   [string]--cache                    Cache generated modules and chunks to improveperformance for multiple incremental builds.[boolean] [default: It's enabled by default when watching]--watch-stdin, --stdin     Stop watching when stdin stream has ended [boolean]--watch-aggregate-timeout  Delay the rebuilt after the first change. Value isa time in ms.                              [number]--watch-poll               Enable polling mode for watching           [string]--hot                      Enables Hot Module Replacement            [boolean]--prefetch                 Prefetch this request (Example: --prefetch./file.js)                                 [string]--provide                  Provide these modules as free vars in all modules(Example: --provide jQuery=jquery)         [string]--labeled-modules          Enables labeled modules                   [boolean]--plugin                   Load this plugin                           [string]--bail                     Report the first error as a hard error instead oftolerating it.            [boolean] [default: null]--profile                  Capture timing information for each module.[boolean] [default: null]Resolving options:--resolve-alias         Redirect module requests                      [string]--resolve-extensions    Redirect module requests                       [array]--resolve-loader-alias  Setup a loader alias for resolving            [string]Optimizing options:--optimize-max-chunks      Try to keep the chunk count below a limit--optimize-min-chunk-size  Minimal size for the created chunk--optimize-minimize        Enable minimizing the output. Usesoptimization.minimizer.                   [boolean]Stats options:--color, --colors               Enables/Disables colors on the console[boolean] [default: (supports-color)]--sort-modules-by               Sorts the modules list by property in module[string]--sort-chunks-by                Sorts the chunks list by property in chunk[string]--sort-assets-by                Sorts the assets list by property in asset[string]--hide-modules                  Hides info about modules             [boolean]--display-exclude               Exclude modules in the output         [string]--display-modules               Display even excluded modules in the output[boolean]--display-max-modules           Sets the maximum number of visible modules inoutput                                [number]--display-chunks                Display chunks in the output         [boolean]--display-entrypoints           Display entry points in the output   [boolean]--display-origins               Display origins of chunks in the output[boolean]--display-cached                Display also cached modules in the output[boolean]--display-cached-assets         Display also cached assets in the output[boolean]--display-reasons               Display reasons about module inclusion in theoutput                               [boolean]--display-depth                 Display distance from entry point for eachmodule                               [boolean]--display-used-exports          Display information about used exports inmodules (Tree Shaking)               [boolean]--display-provided-exports      Display information about exports providedfrom modules                         [boolean]--display-optimization-bailout  Display information about why optimizationbailed out for modules               [boolean]--display-error-details         Display details about errors         [boolean]--display                       Select display preset[string] [choices: "", "verbose", "detailed", "normal", "minimal","errors-only", "none"]--verbose                       Show more details                    [boolean]--info-verbosity                Controls the output of lifecycle messaginge.g. Started watching files...[string] [choices: "none", "info", "verbose"] [default: "info"]--build-delimiter               Display custom text after build output[string]Options:--help, -h     Show help                                             [boolean]--version, -v  Show version number                                   [boolean]--silent       Prevent output from being displayed in stdout         [boolean]--json, -j     Prints the result as JSON.                            [boolean]
View Code

要安装 Webpack 到本项目,可按照你的需要选择以下任意命令运行:

复制代码
# npm i -D 是 npm install --save-dev 的简写,是指安装模块并保存到 package.json 的 devDependencies
# 安装最新稳定版
npm i -D webpack# 安装指定版本
npm i -D webpack@<version># 安装最新体验版本
npm i -D webpack@beta
复制代码

二、快速上手

2.1、创建一个项目或目录

创建一个空项目或一个空目录,不一定需要使用IDE,这里我使用WebStorm

2.2、初始化项目

npm init -y (-y直接跳过提问阶段)

复制代码
name - 包名.
version - 包的版本号。
description - 包的描述。
homepage - 包的官网URL。
author - 包的作者,它的值是你在https://npmjs.org网站的有效账户名,遵循“账户名<邮件>”的规则,例如:zhangsan <zhangsan@163.com>。
contributors - 包的其他贡献者。
dependencies / devDependencies - 生产/开发环境依赖包列表。它们将会被安装在 node_module 目录下。
repository - 包代码的Repo信息,包括type和URL,type可以是git或svn,URL则是包的Repo地址。
main - main 字段指定了程序的主入口文件,require('moduleName') 就会加载这个文件。这个字段的默认值是模块根目录下面的 index.js。
keywords - 关键字
复制代码

package.json详解

2.3、安装webpack

webpack4需要安装webpack-cli:

npm i webpack webpack-cli --save-dev

2.4、创建目录与文件

src/bar.js

复制代码
//定义模块
//部分依赖lodash中的join方法
import {join} from 'lodash'//导出一个默认模块
export default function bar() {function component() {//创建DOM元素var element=document.createElement("h2");//使用join连接数组将结果写入元素的html中element.innerHTML=join(['Hello','Webpack','!'],' ');return element;}//在body中添加子元素document.body.appendChild(component());
}
复制代码

实现使用lodash的join 连接字符串,在网页中输出字符串

依赖lodash、npm安装lodash,在bar.js中import lodash的join方法,输出text

npm i lodash --save

src/index.js

复制代码
//入口文件//导入自定义好的模块
import bar from './bar';
//调用
bar();
复制代码

创建配置文件webpack.config.js

复制代码
//webpack配置文件//依赖node中的path模块
const path=require('path');//定义一个默认模块对象
module.exports={//指定入口文件的位置entry:"./src/index.js",//设置输出结果output: {//路径,将相对路径转绝对路径path:path.resolve(__dirname,'dist'),//文件filename: "bundle.js"}
};
复制代码

path.resolve获取文件的路径,_dirname为当前模块的绝对路径,详细解释如下:

path.resolve()
//作用:path.resolve() 该方法将一些的 路径/路径段 解析为绝对路径。
//语法:path.resolve( [from…],to )
//说明:将参数to位置的字符解析到一个绝对路径里,[from … ]为选填项,路径源;用法:
var path = require("path")     //引入node的path模块path.resolve('/foo/bar', './baz')   // returns '/foo/bar/baz'
path.resolve('/foo/bar', 'baz')   // returns '/foo/bar/baz'
path.resolve('/foo/bar', '/baz')   // returns '/baz'
path.resolve('/foo/bar', '../baz')   // returns '/foo/baz'
path.resolve('home','/foo/bar', '../baz')   // returns '/foo/baz'
path.resolve('home','./foo/bar', '../baz')   // returns '/home/foo/baz'
path.resolve('home','foo/bar', '../baz')   // returns '/home/foo/baz'
//总结:从后向前,若字符以 / 开头,不会拼接到前面的路径;若以 ../ 开头,拼接前面的路径,且不含最后一节路径;若以 ./ 开头 或者没有符号 则拼接前面路径;//另:path.resolve总是返回一个以相对于当前的工作目录(working directory)的绝对路径。
View Code

index.html

webpack创建dist文件在dist中生成打包文件,然后再index.html中引用index.js文件

复制代码
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Hello WebPack</title>
</head>
<body>
<h2>Hello WebPack</h2>
<script src="dist/bundle.js"></script>
</body>
</html>
复制代码

2.5、使用webpack命令打包

可以指定配置文件

webpack --config webpack.config.js

也可以使用默认的配置文件

webpack

打包的结果:

!function(n){var t={};function r(e){if(t[e])return t[e].exports;var u=t[e]={i:e,l:!1,exports:{}};return n[e].call(u.exports,u,u.exports,r),u.l=!0,u.exports}r.m=n,r.c=t,r.d=function(n,t,e){r.o(n,t)||Object.defineProperty(n,t,{enumerable:!0,get:e})},r.r=function(n){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(n,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(n,"__esModule",{value:!0})},r.t=function(n,t){if(1&t&&(n=r(n)),8&t)return n;if(4&t&&"object"==typeof n&&n&&n.__esModule)return n;var e=Object.create(null);if(r.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:n}),2&t&&"string"!=typeof n)for(var u in n)r.d(e,u,function(t){return n[t]}.bind(null,u));return e},r.n=function(n){var t=n&&n.__esModule?function(){return n.default}:function(){return n};return r.d(t,"a",t),t},r.o=function(n,t){return Object.prototype.hasOwnProperty.call(n,t)},r.p="",r(r.s=3)}([function(n,t,r){(function(n,e){var u;
View Code

 bundle.js文件:

2.6、运行

三、核心概念与执行过程

本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle。

从 webpack v4.0.0 开始,可以不用引入一个配置文件。然而,webpack 仍然还是高度可配置的。在开始前你需要先理解几个核心概念:

3.1、模块(Module)

在Webpack里一切皆模块,一个模块对应着一个文件。Webpack 会从配置的Entry开始递归找出所有依赖的模块。

webpack把一切都视为模块,不管是 CSS、JS、Image 还是 HTML 都可以互相引用。Node.js 从最一开始就支持模块化编程。然而,在 web,模块化的支持正缓慢到来。在 web 存在多种支持 JavaScript 模块化的工具,这些工具各有优势和限制。webpack 基于从这些系统获得的经验教训,并将模块的概念应用于项目中的任何文件。

什么是 webpack 模块

对比 Node.js 模块,webpack 模块能够以各种方式表达它们的依赖关系,几个例子如下:

  1. ES2015 import 语句
  2. CommonJS require() 语句
  3. AMD define 和 require 语句
  4. css/sass/less 文件中的 @import 语句。
  5. 样式(url(...))或 HTML 文件(<img src=...>)中的图片链接(image url)

支持的模块类型

webpack 通过 loader 可以支持各种语言和预处理器编写模块。loader 描述了 webpack 如何处理 非 JavaScript(non-JavaScript) _模块_,并且在 bundle 中引入这些依赖。 webpack 社区已经为各种流行语言和语言处理器构建了 loader,包括:

  1. CoffeeScript
  2. TypeScript
  3. ESNext (Babel)
  4. Sass
  5. Less
  6. Stylus

3.2、入口(entry)

入口,Webpack 执行构建的第一步将从 Entry 开始,可抽象成输入。

入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

每个依赖项随即被处理,最后输出到称之为 bundles 的文件中,我们将在下一章节详细讨论这个过程。

可以通过在 webpack 配置中配置 entry 属性,来指定一个入口起点(或多个入口起点)。默认值为 ./src。

接下来我们看一个 entry 配置的最简单例子:

复制代码
webpack.config.jsmodule.exports = {entry: './path/to/my/entry/file.js'
};
复制代码

根据应用程序的特定需求,可以以多种方式配置 entry 属性。

多入口与多出口:

复制代码
{entry: {app: './src/app.js',search: './src/search.js'},output: {filename: '[name].js',path: __dirname + '/dist'}
}// 写入到硬盘:./dist/app.js, ./dist/search.js
复制代码

常用的占位:

  1. [hash]:模块标识符(module identifier)的 hash
  2. [chunkhash]:chunk 内容的 hash
  3. [name]:模块名称,key的名称,非文件名称
  4. [id]:模块标识符(module identifier)
  5. [query]:模块的 query,例如,文件名 ? 后面的字符串

3.3、出口(output)

输出结果,在 Webpack 经过一系列处理并得出最终想要的代码后输出结果。

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。你可以通过在配置中指定一个 output 字段,来配置这些处理过程:

复制代码
webpack.config.jsconst path = require('path');module.exports = {entry: './path/to/my/entry/file.js',output: {path: path.resolve(__dirname, 'dist'),filename: 'my-first-webpack.bundle.js'}
};
复制代码

在上面的示例中,我们通过 output.filename 和 output.path 属性,来告诉 webpack bundle 的名称,以及我们想要 bundle 生成(emit)到哪里。可能你想要了解在代码最上面导入的 path 模块是什么,它是一个 Node.js 核心模块,用于操作文件路径。

示例:

3.4、模块转换器(loader)

模块转换器,用于把模块原内容按照需求转换成新内容。

loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。

本质上,webpack loader 将所有类型的文件,转换为应用程序的依赖图(和最终的 bundle)可以直接引用的模块。

注意,loader 能够 import 导入任何类型的模块(例如 .css 文件),这是 webpack 特有的功能,其他打包程序或任务执行器的可能并不支持。我们认为这种语言扩展是有很必要的,因为这可以使开发人员创建出更准确的依赖关系图。

在更高层面,在 webpack 的配置中 loader 有两个目标:

  1. test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
  2. use 属性,表示进行转换时,应该使用哪个 loader。
复制代码
webpack.config.jsconst path = require('path');const config = {output: {filename: 'my-first-webpack.bundle.js'},module: {rules: [{ test: /\.txt$/, use: 'raw-loader' }]}
};module.exports = config;
复制代码

以上配置中,对一个单独的 module 对象定义了 rules 属性,里面包含两个必须属性:test 和 use。这告诉 webpack 编译器(compiler) 如下信息:

“webpack 编译器,当你碰到「在 require()/import 语句中被解析为 '.txt' 的路径」时,在你对它打包之前,先使用 raw-loader 转换一下。”

3.5、插件(plugins)

扩展插件,在 Webpack 构建流程中的特定时机注入扩展逻辑来改变构建结果或做你想要的事情。

loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。

想要使用一个插件,你只需要 require() 它,然后把它添加到 plugins 数组中。多数插件可以通过选项(option)自定义。你也可以在一个配置文件中因为不同目的而多次使用同一个插件,这时需要通过使用 new 操作符来创建它的一个实例。

复制代码
webpack.config.jsconst HtmlWebpackPlugin = require('html-webpack-plugin'); // 通过 npm 安装
const webpack = require('webpack'); // 用于访问内置插件const config = {module: {rules: [{ test: /\.txt$/, use: 'raw-loader' }]},plugins: [new HtmlWebpackPlugin({template: './src/index.html'})]
};module.exports = config;
复制代码

3.6、模式(mode)

通过选择 development 或 production 之中的一个,来设置 mode 参数,你可以启用相应模式下的 webpack 内置的优化

module.exports = {mode: 'production'
};

webpack4允许我们指定编译使用开发模式还是生产模式,这由mode这个配置来控制,value为枚举值:development/production,分别对应开发模式和生产模式(这个配置可以作为命令行的配置参数也可以作为配置文件中的一个配置项,默认值是production,即生产模式)。

源码还是不支持调试(都用eval函数包住),指定编译时的source-map生成方式,默认值是eval,可以解决问题。

3.7、代码块(Chunk)

一个 Chunk 由多个模块组合而成,用于代码合并与分割。

3.8、WebPack执行过程

Webpack 启动后会从 Entry 里配置的 Module 开始递归解析 Entry 依赖的所有 Module。 每找到一个 Module, 就会根据配置的 Loader 去找出对应的转换规则,对 Module 进行转换后,再解析出当前 Module 依赖的 Module。 这些模块会以 Entry 为单位进行分组,一个 Entry 和其所有依赖的 Module 被分到一个组也就是一个 Chunk。最后 Webpack 会把所有 Chunk 转换成文件输出。 在整个流程中 Webpack 会在恰当的时机执行 Plugin 里定义的逻辑。

Webpack从入口(entry)开始工作,通常这些是JavaScript模块,其中webpack开始其遍历过程。在此过程中,webpack会根据加载器配置评估入口(entry)匹配,这些配置告诉webpack如何转换每个匹配。

入口(entry)本身就是一个模块。当webpack遇到一个入口时,webpack会尝试使用入口的resolve配置将入口与文件系统匹配。除了node_modules之外,我们还可以告诉webpack对特定目录执行查找。也可以调整webpack与文件扩展名匹配的方式,并且可以为目录定义特定的别名。该耗竭与包章涵盖了更详细的这些想法。

如果解析通过失败,webpack会引发运行时错误。如果webpack设法正确解析文件,webpack将根据加载器定义对匹配的文件执行处理。每个加载器对模块内容应用特定的转换。

可以通过多种方式配置加载程序与已解析文件匹配的方式,包括文件类型和文件系统中的位置。Webpack的灵活性甚至允许我们根据文件导入项目的位置对文件应用特定的转换。

对webpack的加载器执行相同的解析过程。Webpack允许我们在确定应使用哪个加载器时应用类似的逻辑。由于这个原因,装载程序已经解析了自己的配置。如果webpack无法执行加载程序查找,则会引发运行时错误。

在实际应用中你可能会遇到各种奇怪复杂的场景,不知道从哪开始。 根据以上总结,你会对 Webpack 有一个整体的认识,这能让你在以后使用 Webpack 的过程中快速知道应该通过配置什么去完成你想要的功能,而不是无从下手。

 下图可以简易的描述出webpack打包过程,该过程主要分为三个阶段:module构建、trunk构建和产出三个阶段:

四、模块转换器Loader

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

loader 是对应用程序中资源文件进行转换。它们是(运行在 Node.js 中的)函数,可以将资源文件作为参数的来源,然后返回新的资源文件。

 

4.1、loader特性

loader 支持链式传递。能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript。

  • loader 可以是同步的,也可以是异步的。
  • loader 运行在 Node.js 中,并且能够执行任何可能的操作。
  • loader 接收查询参数。用于对 loader 传递配置。
  • loader 也能够使用 options 对象进行配置。

除了使用 package.json 常见的 main 属性,还可以将普通的 npm 模块导出为 loader,做法是在 package.json 里定义一个 loader 字段。

插件(plugin)可以为 loader 带来更多特性。

loader 能够产生额外的任意文件。

loader 通过(loader)预处理函数,为 JavaScript 生态系统提供了更多能力。 用户现在可以更加灵活地引入细粒度逻辑,例如压缩、打包、语言翻译和其他更多。

loader 遵循标准的模块解析。多数情况下,loader 将从模块路径(通常将模块路径认为是 npm install, node_modules)解析。

loader 模块需要导出为一个函数,并且使用 Node.js 兼容的 JavaScript 编写。通常使用 npm 进行管理,但是也可以将自定义 loader 作为应用程序中的文件。按照约定,loader 通常被命名为 xxx-loader(例如 json-loader)。

4.2、使用loader的三种方式

(1)、配置(推荐):在 webpack.config.js 文件中指定 loader

module.rules 允许你在 webpack 配置中指定多个 loader。 这是展示 loader 的一种简明方式,并且有助于使代码变得简洁。同时让你对各个 loader 有个全局概览:

复制代码
  module: {rules: [{test: /\.css$/,use: [{ loader: 'style-loader' },{loader: 'css-loader',options: {modules: true}}]}]}
复制代码

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

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

(2)、内联:在每个 import 语句中显式指定 loader

可以在 import 语句或任何等效于 "import" 的方式中指定 loader。使用 ! 将资源中的 loader 分开。分开的每个部分都相对于当前目录解析。

import Styles from 'style-loader!css-loader?modules!./styles.css';

通过前置所有规则及使用 !,可以对应覆盖到配置中的任意 loader。

选项可以传递查询参数,例如 ?key=value&foo=bar,或者一个 JSON 对象,例如 ?{"key":"value","foo":"bar"}。

尽可能使用 module.rules,因为这样可以减少源码中的代码量,并且可以在出错时,更快地调试和定位 loader 中的问题。

(3)、CLI:在 shell 命令中指定它们

你也可以通过 CLI 使用 loader:

webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'

这会对 .jade 文件使用 jade-loader,对 .css 文件使用 style-loader 和 css-loader。

4.3、常见的loader

4.3.1、文件

  • raw-loader 加载文件原始内容(utf-8)
  • val-loader 将代码作为模块执行,并将 exports 转为 JS 代码
  • url-loader 像 file loader 一样工作,但如果文件小于限制,可以返回 data URL
  • file-loader 将文件发送到输出文件夹,并返回(相对)URL

4.3.2、JSON

  • json-loader 加载 JSON 文件(默认包含)
  • json5-loader 加载和转译 JSON 5 文件
  • cson-loader 加载和转译 CSON 文件

4.3.3、转换编译(Transpiling)

  • script-loader 在全局上下文中执行一次 JavaScript 文件(如在 script 标签),不需要解析
  • babel-loader 加载 ES2015+ 代码,然后使用 Babel 转译为 ES5
  • buble-loader 使用 Bublé 加载 ES2015+ 代码,并且将代码转译为 ES5
  • traceur-loader 加载 ES2015+ 代码,然后使用 Traceur 转译为 ES5
  • ts-loader 或 awesome-typescript-loader 像 JavaScript 一样加载 TypeScript 2.0+
  • coffee-loader 像 JavaScript 一样加载 CoffeeScript

4.3.4、模板(Templating)

  • html-loader 导出 HTML 为字符串,需要引用静态资源
  • pug-loader 加载 Pug 模板并返回一个函数
  • jade-loader 加载 Jade 模板并返回一个函数
  • markdown-loader 将 Markdown 转译为 HTML
  • react-markdown-loader 使用 markdown-parse parser(解析器) 将 Markdown 编译为 React 组件
  • posthtml-loader 使用 PostHTML 加载并转换 HTML 文件
  • handlebars-loader 将 Handlebars 转移为 HTML
  • markup-inline-loader 将内联的 SVG/MathML 文件转换为 HTML。在应用于图标字体,或将 CSS 动画应用于 SVG 时非常有用。

4.3.5、样式

  • style-loader 将模块的导出作为样式添加到 DOM 中
  • css-loader 解析 CSS 文件后,使用 import 加载,并且返回 CSS 代码
  • less-loader 加载和转译 LESS 文件
  • sass-loader 加载和转译 SASS/SCSS 文件
  • postcss-loader 使用 PostCSS 加载和转译 CSS/SSS 文件
  • stylus-loader 加载和转译 Stylus 文件

4.3.6、清理和测试(Linting && Testing)

  • mocha-loader 使用 mocha 测试(浏览器/NodeJS)
  • eslint-loader PreLoader,使用 ESLint 清理代码
  • jshint-loader PreLoader,使用 JSHint 清理代码
  • jscs-loader PreLoader,使用 JSCS 检查代码样式
  • coverjs-loader PreLoader,使用 CoverJS 确定测试覆盖率

4.3.7、框架(Frameworks)

  • vue-loader 加载和转译 Vue 组件
  • polymer-loader 使用选择预处理器(preprocessor)处理,并且 require() 类似一等模块(first-class)的 Web 组件
  • angular2-template-loader 加载和转译 Angular 组件

4.4、raw-loader(文件原始内容转换器)

一个可以用于加载文件作为字符串使用的加载器,使用UTF-8编码。

安装

npm i --D raw-loader

 安装结果:

用法一:

通过 webpack 配置、命令行或者内联使用 loader。

复制代码
webpack.config.jsmodule.exports = {module: {rules: [{test: /\.txt$/,use: 'raw-loader'}]}
}
复制代码

在你的项目中

import txt from './file.txt';

用法二:通过命令行(CLI)

webpack --module-bind 'txt=raw-loader'

用法三:在你的项目中

import txt from 'file.txt';

内联使用

import txt from 'raw-loader!./file.txt';

示例:

webpack.config.json

//webpack配置文件//依赖node中的path模块
var path=require('path');//定义一个默认模块对象
module.exports={//指定入口文件的位置,多入口entry:{index:"./src/index.js",main:"./src/main.js"},//设置输出结果output: {//路径,将相对路径转绝对路径path:path.resolve(__dirname,'dist'),//文件,[name]是模块名称,占位filename: "[name].bundle.js"},module: {  //模块处理rules: [ //处理器{test:/\.txt$/,  //当模块的后缀为.txt时匹配use: "raw-loader"  //模块转换器,可以以对象的形式指定参数}]},mode: "development"
};
View Code

src/file1.txt

A loader for webpack that lets you import files as a string.

src/bar.js

复制代码
//定义模块
//部分依赖lodash中的join方法
import {join} from 'lodash';
//导入模块,获得file1.txt中的文件内容,被raw-loader处理
import message from './file1.txt';//导出一个默认模块
export default function bar() {function component() {//创建DOM元素var element=document.createElement("h2");//使用join连接数组将结果写入元素的html中element.innerHTML=join(['Hello','Webpack','!'],' ')+"<br/>"+message;return element;}//在body中添加子元素document.body.appendChild(component());
}
复制代码

运行结果:

内联使用模块处理器:

4.5、CSS Loader(样式处理)

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

  • css-loader: 加载.css文件
  • style-loader:使用<style>将css-loader内部样式注入到我们的HTML页面

css-loader详解:

https://www.npmjs.com/package/css-loader

https://www.webpackjs.com/loaders/css-loader/

style-loader详解:

https://www.npmjs.com/package/style-loader

https://www.webpackjs.com/loaders/style-loader/

4.5.1、安装

//安装
npm i style-loader css-loader -D

4.5.2、配置

复制代码
const path = require("path");module.exports = {entry: './src/index.js',output: {path: path.resolve(__dirname, 'dist'),filename: "bundle.js"},module: {rules: [{test:/\.css/,use:['style-loader',{loader: 'css-loader',options: {sourceMap:true}}]}]},mode: "development"
};
复制代码

4.5.3、定义样式与引用

base.css

复制代码
h2{height: 40px;line-height: 40px;background: crimson;color:#fff;
}
复制代码

bar.js

复制代码
import {join} from 'lodash';
import base from '../css/base.css';export default function bar() {function component() {var element=document.createElement("h2");element.innerHTML=join(['Hello','Webpack!']);return element;}document.body.appendChild(component());
}
复制代码

4.5.4、打包运行

打包:

运行:

生成代码:

4.5.5、注意事项

  1. rules里的数据类型为对象,每一个loader都是一个对象
  2. test表示loader要处理什么类型的文件,这里用了一个正则去匹配文件类型
  3. use表示要使用哪个loader,它的值是个数组,loader的使用顺序是从后往前
  4. 这个loader的意思为,在入口文件里找到.css类型的文件,先拿css-loader去处理成浏览器认识的css,再拿style-loader把处理后的css放在页面的style标签里

4.6、sass-loader(加载和转译 SASS/SCSS 文件)

加载sass或scss文件并转译成css

用css-loader或raw-loader 转换成一个JS模块或用ExtractTextPlugin插件将样式分隔成一个单独文件。

安装

npm i sass-loader node-sass --D

 

node-sass 和 webpack 是 sass-loader 的 peerDependency,因此能够精确控制它们的版本。

示例

css/baseScss.scss

按 Ctrl+C 复制代码
$height:50px; $color:#3366ff; h2{ background: $color; height: $height; line-height: $height; color: white; padding-left: $height/5; }
按 Ctrl+C 复制代码

 

通过将 style-loader 和 css-loader 与 sass-loader 链式调用,可以立刻将样式作用在 DOM 元素。

配置webpack.config.json

复制代码
//webpack配置文件//依赖node中的path模块
var path=require('path');//定义一个默认模块对象
module.exports={//指定入口文件的位置,多入口entry:{index:"./src/index.js",main:"./src/main.js"},//设置输出结果output: {//路径,将相对路径转绝对路径path:path.resolve(__dirname,'dist'),//文件,[name]是模块名称,占位filename: "[name].bundle.js"},module: {  //模块处理rules: [ //处理器{test:/\.txt$/,  //当模块的后缀为.txt时匹配use: "raw-loader"  //模块转换器,可以以对象的形式指定参数},{test:/\.css$/,  //匹配所有css模块//use表示要使用哪个loader,它的值是个数组,loader的使用顺序是从后往前use: ["style-loader",{loader: "css-loader",  //转换器名称options: {  //配置选项modules:true,  //模块化sourceMap:true  //是否生成调试文件}}]  //使用多个模块转换器},{test: /\.scss$/,use: [{loader: "style-loader" // 将 JS 字符串生成为 style 节点}, {loader: "css-loader" // 将 CSS 转化成 CommonJS 模块}, {loader: "sass-loader" // 将 Scss 编译成 CSS}]}]},mode: "development"
};
复制代码

 

导入scss作为模块

复制代码
//定义模块
//部分依赖lodash中的join方法
import {join} from 'lodash';
//导入模块,获得file1.txt中的文件内容,被raw-loader处理
import message from './file1.txt';
//导入样式文件
//import '../css/baseCss.css'
//导入预处理样式文件
import '../css/baseScss.scss'//导出一个默认模块
export default function bar() {function component() {//创建DOM元素var element=document.createElement("h2");//使用join连接数组将结果写入元素的html中element.innerHTML=join(['Hello','Webpack','!'],' ')+"<br/>"+message;return element;}//在body中添加子元素document.body.appendChild(component());
}
复制代码

打包后运行结果:

通常,生产环境下比较推荐的做法是,使用 ExtractTextPlugin 将样式表抽离成专门的单独文件。这样,样式表将不再依赖于 JavaScript:

复制代码
const ExtractTextPlugin = require("extract-text-webpack-plugin");const extractSass = new ExtractTextPlugin({filename: "[name].[contenthash].css",disable: process.env.NODE_ENV === "development"
});module.exports = {...module
:
{rules: [{test: /\.scss$/,use: extractSass.extract({use: [{loader: "css-loader"}, {loader: "sass-loader"}],
// 在开发环境使用 style-loaderfallback: "style-loader"})}]
}
,
plugins: [extractSass
]
}
;
复制代码

 

4.7、url-loader(路径处理器)

 Webpack 允许你在js文件中require图片 , 通过 url-loader和file-loader来预处理图片文件.

安装

npm install --save-dev url-loader file-loader

用法

url-loader 功能类似于 file-loader,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL。

import img from './image.png'

配置

复制代码
webpack.config.jsmodule.exports = {module: {rules: [{test: /\.(png|jpg|gif)$/,use: [{loader: 'url-loader',options: {limit: 8192}}]}]}
}
复制代码

示例

复制代码
var img1 = document.createElement("img");
img1.src = require("./small.png");
document.body.appendChild(img1);var img2 = document.createElement("img");
img2.src = require("./big.png");
document.body.appendChild(img2);
复制代码

五、插件plugins

 

5.1、单独提取CSS

运行后,在dist目录里只有两个文件,一个bundle.js一个index.html文件,并没有css文件,同时打开index.html源码后也没有发现有css的内容。这是因为style-loader的作用,它把css一同打包到了js文件里,js文件在能过DOM动态创建style标签并添加到页面里。所以css的内容已经放到了index.bundle.js里。

 这种形式只有当文件内容不多的时候可以使用,如果CSS的内容以及JS的内容非常的多,把两块都打包到一个文件里就会增加文件的体积,用户打开页面的时候下载速度会受影响,同时影响用户体验。这就需要把CSS文件单独拎出来,那需要一个插件来配合loader才能完成

mini-css-extract-plugin

webpack版本需要4.3以上,低版本请使用extract-text-webpack-plugin

使用步骤:

1、安装

npm i mini-css-extract-plugin -D

2、在webpack.config.js里引入模块

const MiniCssExtractPlugin=require("mini-css-extract-plugin");

3、写入plugins

plugins:[
new HtmlWebpackPlugin({
title:'tom',
template:'./src/template.html',
filename:'index.html',
}),
new MiniCssExtractPlugin({
filename:'css/index.css' //文件目录会放入output.path里
}),
]

4、写入loader

module:{
rules:[
{
test:/\.css$/,
use:[MiniCssExtractPlugin.loader,"css-loader"] //代替style-loader
}
]
}

执行命令npm run build后可以看到dist目录里已经多了一个css文件夹,这个文件夹里放了一个index.css文件。打开index.html源码看到css文件已经通过link标签引入,这些功能都是mini-css-extract-plugin所做的

转载于:https://www.cnblogs.com/xiongshuangping/p/10110712.html

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 快速手册-风格指南

    风格指南&#xff1a;style guide 单一职责 对所有的组件、服务等等应用单一职责原则 (SRP)。这样可以让应用更干净、更易读、更易维护、更易测试。 1.单组件文件非常容易阅读、维护&#xff0c;并能防止在版本控制系统里与团队冲突。 2.单组件文件可以防止一些隐蔽的程序缺陷…...

    2024/4/12 5:04:28
  2. 双眼皮消失了怎么回来

    ...

    2024/4/12 5:04:52
  3. 双眼皮线头掉怎么办

    ...

    2024/4/6 0:56:28
  4. Angular通过指令创建在指定文件夹下,模块中如果想包含模块也是一样的

    ng g component mapDailyPatrol --moduledaily-patrol...

    2024/4/12 16:59:46
  5. 双眼皮线埋的太深了

    ...

    2024/4/11 19:30:09
  6. 双眼皮夏天去做

    ...

    2024/4/6 0:56:26
  7. 双眼皮吸脂视频全过程

    ...

    2024/4/19 9:47:50
  8. 双眼皮吸脂埋线

    ...

    2024/4/6 0:56:23
  9. 双眼皮武汉诠美更佳

    ...

    2024/4/15 8:25:38
  10. AngularJS-5-事件绑定

    一、举例 <html ng-app"lesson" ng-controller"lesson4"> <table> <thead><th>ID</th><th>姓名</th><th>年龄</th><th>星座</th><th>工作年限</th><th>操作</t…...

    2024/4/18 4:21:14
  11. 双眼皮为什么显眼睛大

    ...

    2024/4/18 7:31:57
  12. 双眼皮突然一大一小

    ...

    2024/4/18 18:00:52
  13. 高德地图使用插件报错AMap.Xxx is not constructor

    报错的原因是在代码中使用了地图插件例如ToolBar、OverView、Scale&#xff0c;但是并没有加载插件 解决方案 同步加载插件&#xff1a;在引入地图的script标签进行如下拼接&#xff0c;多个插件用逗号分隔 <script type"text/javascript" src"https://we…...

    2024/4/12 5:04:40
  14. 双眼皮太深了怎么修复

    ...

    2024/4/18 16:03:59
  15. vue+高德地图信息窗体如何实现点击事件

    vue高德地图信息窗体如何实现点击事件概述代码概述 若有帮助到你&#xff0c;麻烦点一波关注&#xff0c;博主会持续推出Echarts,D3,地图,Three.js方面的文章~~~ 在高德地图中&#xff0c;使用infoWindow来创建信息窗体&#xff0c;如果是原生的htmlcss&#xff0c;可以很方便…...

    2024/4/15 21:29:14
  16. 双眼皮损伤结膜

    ...

    2024/4/12 5:05:40
  17. 双眼皮水肿怎么治疗

    ...

    2024/4/6 0:56:17
  18. 双眼皮术后注意长

    ...

    2024/4/6 0:56:16
  19. 双眼皮术后增生问题

    ...

    2024/4/12 8:17:22
  20. Weex meets Vue,记一次 Weex 前端团队的讨论

    介绍一下背景&#xff0c;这次讨论发生在 JSConf 期间&#xff0c;正好 yyx990803 难得和团队其他同学见面认识 领衔主演&#xff1a;yyx990803 主演&#xff1a;DoranYun Hanks10100 IskenHuang Jinjiang MrRaindrop songsiqi terrykingcha vczero yuanyan Tancy Fkysly (对应…...

    2024/4/12 5:05:28

最新文章

  1. 2024鸿蒙迎来爆发,有必要转行鸿蒙开发吗?

    鸿蒙系统&#xff0c;作为华为自主研发的操作系统&#xff0c;正在迎来前所未有的爆发&#xff0c;以强大的分布式技术和创新能力&#xff0c;不仅支持多种终端设备&#xff0c;更在构建一个日益完善的生态系统&#xff0c;在当前的科技浪潮中。面对这样的发展趋势&#xff0c;…...

    2024/4/20 2:46:32
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. K8S容器空间不足问题分析和解决

    如上图&#xff0c;今天测试环境的K8S平台出现了一个问题&#xff0c;其中的一个容器报错&#xff1a;Free disk space below threshold. Available: 3223552 bytes (threshold: 10485760B)&#xff0c;意思服务器硬盘空间不够了。这个问题怎么产生的&#xff0c;又怎么解决的呢…...

    2024/4/17 4:26:56
  4. CrossOver玩游戏会损害电脑吗 CrossOver玩游戏会卡吗 Mac玩游戏 crossover24免费激活

    CrossOver是一款可以在macOS上运行Windows应用程序的软件&#xff0c;它利用了Wine技术&#xff0c;无需安装虚拟机或双系统&#xff0c;可以直接在苹果系统下运行Windows游戏。那么&#xff0c;使用CrossOver玩游戏会损害电脑吗&#xff1f;CrossOver玩游戏会卡吗&#xff1f;…...

    2024/4/17 10:00:41
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/4/19 14:24:02
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/4/19 18:20:22
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/19 11:57:31
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/4/19 11:57:31
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/19 11:57:52
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/19 11:57:53
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/19 11:58:14
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/19 11:58:20
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/19 23:45:49
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/4/19 11:58:39
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/19 11:58:51
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/19 18:09:34
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/19 11:59:15
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/19 11:59:23
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/4/19 11:59:44
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/19 11:59:48
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/19 12:00:06
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/19 16:57:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/4/19 12:00:25
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/19 12:00:40
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57