Dowemo

Source address: http://www. Cnblogs. com/skylor/p/7008756. Html click on the link.

If you:

  • )
  • Javascript nodejs basics
  • Some common commands are used, mkdir, cd etc.
  • Will use npm
  • You might want to have a deeper understanding of the web pack, perhaps at this point you've a problem with the web pack

So, please continue reading:


What's a web pack, why use a web pack

The web pack is official to define her:

Webpack is a tool for building javascript modules in our application.


It's just a wrapper. ( a wrapper: it's done to analyze your project structure, find the javascript module and some other browsers that cannot run directly ( scss, ha, etc ), and package it into the appropriate format for the browser to use. )

The package is too much, so why choose her. Because she's the following features

  • Additional modules are loaded as needed
  • AMD define
  • AMD requireLoad as required
  • CommonJS exports
  • CommonJS require
  • CommonJS Require. Resolve.
  • Require stitching Require (./fi & t + le ).
  • Debug support SourceUrl, SourceMaps
  • ES2015 import/ export
  • Require ( guided ) Expression in Require (./templates/+ template ).
  • Generate a separate package
  • Indirect require: var r = require; R ("./file").
  • Compression uglify
  • Configurable use common bundleBuilding multiple pages
  • More than one bundle
  • Node. Js built-in library. Require ( path )
  • Some variables for node. Js are available: process, __dir/filename , global
  • Rich
  • loaders, transforms
  • Browser replacement Web_modules , Web. Js. , Package. Json. Field, alias config option
  • With a file system: requireFile
  • Execution time ( runtime ) is low: 243B + 20B per module + 4B per dependency
  • Open the file. watch) mode
  • 等等.

I mean, I mean, I mean.

If you've been tempted to be in one of these situations:

  • Don't be careful to introduce some unnecessary stylesheets or js libraries into production environments, resulting in larger project volume
  • Encountered a scope problem - whether from css or javascript
  • Keep looking for a good system that lets you use node or bower modules in javascript code, or rely on a series of crazy backend configurations to properly use those modules
  • You need to optimize the resource distribution mechanism, but it'll destroy something.

So you can benefit from the webpack. It solves these problems easily by letting javascript replace the brain 's brain to care about dependencies and loading order. What's the best part. Webpack can even run seamlessly on the server, which means that you can still use webpack to build incremental enhanced sites.

Install

Before you start, make sure you've the latest version of Node.js. With the latest lts version of Node.js, it's ideal. With older versions, you may encounter a variety of problems because they may lack a webpack feature or lack of a relevant package package.

Local installation

Use npm:


npm install --save-dev webpack 


npm install --save-dev webpack@<version> 





  • After you've installed the webpack locally, you can. Node_modules/. Bin/webpack. Accessing its bin version.

Global installation



npm install --global webpack 






But don't recommend doing this because: The webpack is locked to the specified version, and the build failure may result in a different version of the webpack.

Configure



In many cases, the problems you encounter in the use of a web pack are configuration issues, and read the configuration below, and 90% problems should be solved.

Create a new webpack.config.js file in the root directory to declare the configuration of the webpack, and you can specify a specific config file: Webpack --config mywebpack. Config. Js.



const path = require('path');



module.exports = { 


 entry:"./app/entry",//string | object | array entry: ["./app/entry1","./app/entry2"],


 entry: {


 a:"./app/entry-a",


 b: ["./app/entry-b1","./app/entry-b2"]


 },


//这里应用程序开始执行


//webpack 开始打包



 output: {


//webpack 如何输出结果的相关选项



 path: path.resolve(__dirname,"dist"),//string


//所有输出文件的目标路径


//必须是绝对路径(使用 Node.js 的 path 模块)


//PS:__dirname指的是根目录



 filename:"bundle.js",//string filename:"[name].js",//用于多个入口点(entry point)(出口点?)


 filename:"[chunkhash].js",//用于长效缓存


//「入口分块(entry chunk)」的文件名模板(出口分块?)



 publicPath:"/assets/",//string publicPath:"",


 publicPath:"https://cdn.example.com/",


//输出解析文件的目录,url 相对于 HTML 页面



 library:"MyLibrary",//string,


//导出库(exported library)的名称



 libraryTarget:"umd",//通用模块定义 libraryTarget:"umd2",//通用模块定义


 libraryTarget:"commonjs2",//exported with module.exports


 libraryTarget:"commonjs-module",//使用 module.exports 导出


 libraryTarget:"commonjs",//作为 exports 的属性导出


 libraryTarget:"amd",//使用 AMD 定义方法来定义


 libraryTarget:"this",//在 this 上设置属性


 libraryTarget:"var",//变量定义于根作用域下


 libraryTarget:"assign",//盲分配(blind assignment)


 libraryTarget:"window",//在 window 对象上设置属性


 libraryTarget:"global",//property set to global object


 libraryTarget:"jsonp",//jsonp wrapper


//导出库(exported library)的类型



/* 高级输出配置 */


 pathinfo: true,//boolean


//在生成代码时,引入相关的模块、导出、请求等有帮助的路径信息。



 chunkFilename:"[id].js",


 chunkFilename:"[chunkhash].js",//长效缓存(/guides/caching)


//「附加分块(additional chunk)」的文件名模板



 jsonpFunction:"myWebpackJsonp",//string


//用于加载分块的 JSONP 函数名



 sourceMapFilename:"[file].map",//string


 sourceMapFilename:"sourcemaps/[file].map",//string


//「source map 位置」的文件名模板



 devtoolModuleFilenameTemplate:"webpack:///[resource-path]",//string


//「devtool 中模块」的文件名模板



 devtoolFallbackModuleFilenameTemplate:"webpack:///[resource-path]?[hash]",//string


//「devtool 中模块」的文件名模板(用于冲突)



 umdNamedDefine: true,//boolean


//在 UMD 库中使用命名的 AMD 模块



 crossOriginLoading:"use-credentials",//枚举


 crossOriginLoading:"anonymous",


 crossOriginLoading: false,


//指定运行时如何发出跨域请求问题



/* 专家级输出配置(自行承担风险) */


 devtoolLineToLine: {


 test:/.jsx$/


 },


//为这些模块使用 1:1 映射 SourceMaps(快速)



 hotUpdateMainFilename:"[hash].hot-update.json",//string


//「HMR 清单」的文件名模板



 hotUpdateChunkFilename:"[id].[hash].hot-update.js",//string


//「HMR 分块」的文件名模板



 sourcePrefix:"t",//string


//包内前置式模块资源具有更好可读性


 },



 module: {


//关于模块配置



 rules: [


//模块规则(配置 loader、解析器等选项)



 {


 test:/.jsx?$/,


 include: [


 path.resolve(__dirname,"app")


 ],


 exclude: [


 path.resolve(__dirname,"app/demo-files")


 ],


//这里是匹配条件,每个选项都接收一个正则表达式或字符串


//test 和 include 具有相同的作用,都是必须匹配选项


//exclude 是必不匹配选项(优先于 test 和 include)


//最佳实践:


//- 只在 test 和 文件名匹配 中使用正则表达式


//- 在 include 和 exclude 中使用绝对路径数组


//- 尽量避免 exclude,更倾向于使用 include



 issuer: { test, include, exclude },


//issuer 条件(导入源)



 enforce:"pre",


 enforce:"post",


//标识应用这些规则,即使规则覆盖(高级选项)



 loader:"babel-loader",


//应该应用的 loader,它相对上下文解析


//为了更清晰,`-loader` 后缀在 webpack 2 中不再是可选的


//查看 webpack 1 升级指南。



 options: {


 presets: ["es2015"]


 },


//loader 的可选项


 },



 {


 test:".html$"



 use: [


//应用多个 loader 和选项


"htmllint-loader",


 {


 loader:"html-loader",


 options: {


/*.. . */


 }


 }


 ]


 },



 { oneOf: [/* rules */] },


//只使用这些嵌套规则之一



 { rules: [/* rules */] },


//使用所有这些嵌套规则(合并可用条件)



 { resource: { and: [/* 条件 */] } },


//仅当所有条件都匹配时才匹配



 { resource: { or: [/* 条件 */] } },


 { resource: [/* 条件 */] },


//任意条件匹配时匹配(默认为数组)



 { resource: { not:/* 条件 */} }


//条件不匹配时匹配


 ],



/* 高级模块配置 */


 noParse: [


/special-library.js$/


 ],


//不解析这里的模块



 unknownContextRequest:".",


 unknownContextRecursive: true,


 unknownContextRegExp:/^./.*$/,


 unknownContextCritical: true,


 exprContextRequest:".",


 exprContextRegExp:/^./.*$/,


 exprContextRecursive: true,


 exprContextCritical: true,


 wrappedContextRegExp:/.*/,


 wrappedContextRecursive: true,


 wrappedContextCritical: false,


//specifies default behavior for dynamic requests


 },



 resolve: {


//解析模块请求的选项


//(不适用于对 loader 解析)



 modules: [


"node_modules",


 path.resolve(__dirname,"app")


 ],


//用于查找模块的目录



 extensions: [".js",".json",".jsx",".css"],


//使用的扩展名



 alias: {


//模块别名列表



"module":"new-module",


//起别名:"module" ->"new-module" 和"module/path/file" ->"new-module/path/file"



"only-module$":"new-module",


//起别名"only-module" ->"new-module",但不匹配"module/path/file" ->"new-module/path/file"



"module": path.resolve(__dirname,"app/third/module.js"),


//起别名"module" ->"./app/third/module.js" 和"module/file" 会导致错误


//模块别名相对于当前上下文导入


 },


/* 可供选择的别名语法 */alias: [


 {


 name:"module",


//旧的请求



 alias:"new-module",


//新的请求



 onlyModule: true


//如果为 true,只有"module" 是别名


//如果为 false,"module/inner/path" 也是别名


 }


 ],



/* 高级解析选项 */


 symlinks: true,


//遵循符号链接(symlinks)到新位置



 descriptionFiles: ["package.json"],


//从 package 描述中读取的文件



 mainFields: ["main"],


//从描述文件中读取的属性


//当请求文件夹时



 aliasFields: ["browser"],


//从描述文件中读取的属性


//以对此 package 的请求起别名



 enforceExtension: false,


//如果为 true,请求必不包括扩展名


//如果为 false,请求可以包括扩展名



 moduleExtensions: ["-module"],


 enforceModuleExtension: false,


//类似 extensions/enforceExtension,但是用模块名替换文件



 unsafeCache: true,


 unsafeCache: {},


//为解析的请求启用缓存


//这是不安全,因为文件夹结构可能会改动


//但是性能改善是很大的



 cachePredicate: (path, request) => true,


//predicate function which selects requests for caching



 plugins: [


//...


 ]


//应用于解析器的附加插件


 },



 performance: {


 hints:"warning",//枚举 hints:"error",//性能提示中抛出错误


 hints: false,//关闭性能提示


 maxAssetSize: 200000,//整数类型(以字节为单位)


 maxEntrypointSize: 400000,//整数类型(以字节为单位)


 assetFilter: function(assetFilename) {


//提供资源文件名的断言函数


 return assetFilename.endsWith('.css') || assetFilename.endsWith('.js');


 }


 },



 devtool:"source-map",//enum devtool:"inline-source-map",//嵌入到源文件中


 devtool:"eval-source-map",//将 SourceMap 嵌入到每个模块中


 devtool:"hidden-source-map",//SourceMap 不在源文件中引用


 devtool:"cheap-source-map",//没有模块映射(module mappings)的 SourceMap 低级变体(cheap-variant)


 devtool:"cheap-module-source-map",//有模块映射(module mappings)的 SourceMap 低级变体


 devtool:"eval",//没有模块映射,而是命名模块。以牺牲细节达到最快。


//通过在浏览器调试工具(browser devtools)中添加元信息(meta info)增强调试


//牺牲了构建速度的 `source-map' 是最详细的。



 context: __dirname,//string(绝对路径!)


//webpack 的主目录


//entry 和 module.rules.loader 选项


//相对于此目录解析



 target:"web",//枚举 target:"webworker",//WebWorker


 target:"node",//node.js 通过 require


 target:"async-node",//Node.js 通过 fs and vm


 target:"node-webkit",//nw.js


 target:"electron-main",//electron,主进程(main process)


 target:"electron-renderer",//electron,渲染进程(renderer process)


 target: (compiler) => {/*.. . */},//自定义


//包(bundle)应该运行的环境


//更改 块加载行为(chunk loading behavior) 和 可用模块(available module)



 externals: ["react",/^@angular//], externals:"react",//string(精确匹配)


 externals:/^[a-z-]+($|/)/,//正则


 externals: {//对象


 angular:"this angular",//this["angular"]


 react: {//UMD


 commonjs:"react",


 commonjs2:"react",


 amd:"react",


 root:"React"


 }


 },


 externals: (request) => {/*.. . */return"commonjs" + request }


//不要遵循/打包这些模块,而是在运行时从环境中请求他们



 stats:"errors-only", stats: {//object


 assets: true,


 colors: true,


 errors: true,


 errorDetails: true,


 hash: true,


//...


 },


//精确控制要显示的 bundle 信息



 devServer: {


 proxy: {//proxy URLs to backend development server


 '/api': 'http://localhost:3000'


 },


 contentBase: path.join(__dirname, 'public'),//boolean | string | array, static file location


 compress: true,//enable gzip compression


 historyApiFallback: true,//true for index.html upon 404, object for multiple paths


 hot: true,//hot module replacement. Depends on HotModuleReplacementPlugin


 https: false,//true for self-signed, object for cert authority


 noInfo: true,//only errors & warns on hot reload


//...


 },



 plugins: [


//...


 ],


//附加插件列表



/* 高级配置 */


 resolveLoader: {/* 等同于 resolve */}


//独立解析选项的 loader



 profile: true,//boolean


//捕获时机信息



 bail: true,//boolean


//在第一个错误出错时抛出,而不是无视错误。



 cache: false,//boolean


//禁用/启用缓存



 watch: true,//boolean


//启用观察



 watchOptions: {


 aggregateTimeout: 1000,//in ms


//将多个更改聚合到单个重构建(rebuild)



 poll: true,


 poll: 500,//间隔单位 ms


//启用轮询观察模式


//必须用在不通知更改的文件系统中


//即 nfs shares(译者注:Network FileSystem,最大的功能就是可以透過網路,讓不同的機器、不同的作業系統、可以彼此分享個別的檔案 ( share file ))


 },



 node: {


/* TODO */


 },



 recordsPath: path.resolve(__dirname,"build/records.json"),


 recordsInputPath: path.resolve(__dirname,"build/records.json"),


 recordsOutputPath: path.resolve(__dirname,"build/records.json"),//TODO}





Split code ( code separation )


Code separation is one of the most prominent features in the webpack. You can separate your code into different bundles, and then you can load these files as you want to load them.

  • For example, when a user navigates to a matching path by, or when the user triggers an event, the corresponding file is loaded. If you use the correct way to use it, this allows us to have smaller bundles and can control the resource load priority so that it's important to load time on your application.

In general, you can complete two types of code separation work by using webpack:

Separation by resource

One, separate third-party libraries

Modern popular development sites, or more, use a lot of libraries, and these libraries often don't change frequently, and pack them together. If we've the code in the library ( library ), keep in with a bundle that's independent of the application code, we can use the browser cache mechanism to cache the files.

To complete this goal, no matter how the application code changes, vendorFile name in file name hashParts must remain unchanged. Learn how to use. CommonsChunkPluginDetach Vendor/library Code.

You might think of multiple entries, like this:


var path = require('path');



module.exports = function(env) { 


 return {


 entry: {


 main: './index.js',


 vendor: 'moment'


 },


 output: {


 filename: '[name].[chunkhash].js',


 path: path.resolve(__dirname, 'dist')


 }


 }


}






Once again, you can see that two bundles are generated. However, if you look at their code, it's found that the moment code appears in both files. The reason is that the moment is the main application ( for example, Index. Js. Dependency module, each entry starting point will pack its own dependency module.

For this reason we need to use commonschunkplugin, this is a very complex. It basically allows us to extract all of the common modules from different bundles and add them to the public bundle. If the public bundle doesn't exist, then it creates a.


var webpack = require('webpack'); 


var path = require('path');



module.exports = function(env) { 


 return {


 entry: {


 main: './index.js',


 vendor: 'moment'


 },


 output: {


 filename: '[name].[chunkhash].js',


 path: path.resolve(__dirname, 'dist')


 },


 plugins: [


 new webpack.optimize.CommonsChunkPlugin({


 name: 'vendor'//指定公共 bundle 的名字。


 })


 ]


 }


}






However, the hashcode of the file for this vendor is also different from each compilation, so you can use manifest, as follows:


var webpack = require('webpack'); 


var path = require('path');



module.exports = function(env) { 


 return {


 entry: {


 main: './index.js',


 vendor: 'moment'


 },


 output: {


 filename: '[name].[chunkhash].js',


 path: path.resolve(__dirname, 'dist')


 },


 plugins: [


 new webpack.optimize.CommonsChunkPlugin({


 names: ['vendor', 'manifest']//指定公共 bundle 的名字。


 })


 ]


 }


};





Summarize using commonschunkplugin:


var webpack = require('webpack'); 


var path = require('path');



module.exports = function() { 


 return {


 entry: {


 main: './index.js'//Notice that we do not have an explicit vendor entry here


 },


 output: {


 filename: '[name].[chunkhash].js',


 path: path.resolve(__dirname, 'dist')


 },


 plugins: [


 new webpack.optimize.CommonsChunkPlugin({


 name: 'vendor',


 minChunks: function (module) {


//this assumes your vendor imports exist in the node_modules directory


 return module.context && module.context.indexOf('node_modules')!== -1;


 }


 }),


//CommonChunksPlugin will now extract all the common modules from vendor and main bundles


 new webpack.optimize.CommonsChunkPlugin({


 name: 'manifest'//But since there are no more common modules between them we end up with just the runtime code included in the manifest file


 })


 ]


 };


}






Can use dllplugin ( providing a separate packaging approach can greatly improve build time performance )


new webpack.DllPlugin({ 


 path: `${__dirname}/manifest.json`,


 name: '[name]',


 context: __dirname,


 })






Two, separate css

In order to package css files with webpack, you can introduce css into your javascript code like other modules, while using css-loader ( like the js module output css ), you can also choose to use extracttextwebpackplugin to put the css file out and output the css file.

Why use this, if not, then you might be:

I & tall the css loader:


npm install --save-dev css-loader style-loader 






Web pack configuration:


module.exports = { 


 module: {


 rules: [{


 test:/.css$/,


 use: [ 'style-loader', 'css-loader' ]


 }]


 }


}






However, css will be packaged with your javascript, and after the initial load, it's done. <style> Label injection style and then work on page.

There's a disadvantage that you can't use the browser 's ability to load css asynchronously and concurrently. Instead, your page needs to wait for the entire javascript file to be loaded before it can be rendered.

It can be used. ExtractTextWebpackPluginHelp you pack css separately to solve the problem above.

I & tall:


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





Add to the configuration using her:


var ExtractTextPlugin = require('extract-text-webpack-plugin');


module.exports = { 


 module: {


 rules: [{


 test:/.css$/,


 use: [ 'style-loader', 'css-loader' ]


 use: ExtractTextPlugin.extract({


 use: 'css-loader'


 })


 }]


 },


 plugins: [


 new ExtractTextPlugin('styles.css'),


 ]


}






Ok, css separation complete.

Separation according to engineering requirements

Once the project reaches a certain degree, there will be demand loading. The next step is how to split your bundle into chunks that can be downloaded asynchronously. For example, this allows you to first provide a minimum boot bundle and load other features asynchronously later. If you don't need to be loaded, you can skip.

Webpack supports two similar techniques to accomplish this: Use import ( ) ( recommended, ecmascript proposal ) and require. Stop ( ) ( legacy, webpack, this isn't covered here ).

Import ( )

An ES2015 loader specification defines the import ( ) as a method for dynamically loading ES2015 modules at runtime ( runtime ).

It takes import ( ) as a ( split-point ) and converts the introduced modules as a separate chunk of chunks. Import ( ) takes the module name as a parameter and returns a promoise object, the import ( name ) -> promise.

For example:


function determineDate() { 


 import('moment').then(function(moment) {


 console.log(moment().format());


 }).catch(function(err) {


 console.log('Failed to load moment', err);


 });


}



determineDate(); 







  • Note that this is similar because it requires at least the location information of the file. Import ( foo ) It's. Fully dynamic statement Can cause failure. This is because foo can be any file in any path in a system or project. Import ( ) At least the information that should be perceived is where the module is located, so packaging will be limited to a specific directory or a set of files.

For example, Import ( `./locale/$ % 7blanguage % 7d. Json ). Will make /locale Each of the directories Json. It's packed into ( split-point ). At runtime ( runtime ), when the variable is computed languageAnd when, like, English. Json. Or or or Germany. Json. Such files are available for use. So please keep in mind. Import ( ) When, The path must contain path information or full static path. ( as in the example above ) "moments"' Same ).

Using a promise polyfill

Use it because: Import ( ) Internally dependent PromiseIf you want to use import ( ) in an older version of the browser, remember to use polyfill ( for example, es6-promise or promise-polyfill ) to shim promise.

Entry configuration:


import Es6Promise from 'es6-promise'; 


Es6Promise.polyfill(); 


//或


import 'es6-promise/auto'; 


//或


import Promise from 'promise-polyfill'; 


if (!window.Promise) { 


 window.Promise = Promise;


}






Custom chunk name

Here's a new magic comment for the web pack 2.4.0.".


import(/* webpackChunkName:"my-chunk-name" */'module'); 






Match babel using

Import ( ) is a feature that belongs to stage 3 and needs to install/add syntax-dynamic-import to avoid parser errors.


npm install --save-dev babel-core babel-loader babel-plugin-syntax-dynamic-import babel-preset-es2015 






Then you can use it:


function determineDate() { 


 import('moment')


. then(moment => moment().format('LLLL'))


. then(str => console.log(str))


. catch(err => console.log('Failed to load moment', err));


}



determineDate(); 







But your web pack has a profile like this to modify it:


module.exports = { 


 entry: './index-es2015.js',


 output: {


 filename: 'dist.js',


 },


 module: {


 rules: [{


 test:/.js$/,


 exclude:/(node_modules)/,


 use: [{


 loader: 'babel-loader',


 options: {


 presets: [['es2015', {modules: false}]],


 plugins: ['syntax-dynamic-import']


 }


 }]


 }]


 }


};






No use Syntax-dynamic-import The will cause the build to fail, and prompt:

  • Module build failed ( module build fails ): Syntaxerror: 'import 'and 'export 'may only appear at the top level ( 'import 'and 'export 'can only appear on top ), or prompt.
  • Module build failed ( module build fails ): Syntaxerror: unexpected token, expected %
Use Async/await

Import ( name ) -> promise It returns a promise, so, Async/await Great method; so how to use it:

I & tall the:


npm install --save-dev babel-plugin-transform-async-to-generator babel-plugin-transform-regenerator babel-plugin-transform-runtime 






And then you can use it:


async function determineDate() { 


 const moment = await import('moment');


 return moment().format('LLLL');


}



determineDate().then(str => console.log(str)); 







Of course, the are used:


module.exports = { 


 entry: './index-es2017.js',


 output: {


 filename: 'dist.js',


 },


 module: {


 rules: [{


 test:/.js$/,


 exclude:/(node_modules)/,


 use: [{


 loader: 'babel-loader',


 options: {


 presets: [['es2015', {modules: false}]],


 plugins: [


 'syntax-dynamic-import',


 'transform-async-to-generator',


 'transform-regenerator',


 'transform-runtime'


 ]


 }


 }]


 }]


 }


};






Import ( ) imports the entire module namespace

It's important to note that import ( ) imports the entire module namespace. For example:


//示例 1: 最顶层 import


import * as Component from './component'; 


//示例 2: 使用 import() 进行代码分离


import('./component').then(Component =>/*.. . */); 





However, when using import ( ) with a ES2015 module, you must explicitly access the default export and naming export:

async function main() { 


//解构赋值用法示例


 const { default: Component } = await 


 import('./component');


//行内用法示例


 render((await import('./component')).default);


}






















Copyright © 2011 Dowemo All rights reserved.    Creative Commons   AboutUs