table of Contents
Sample code is hosted: http://www.github.com/dashnowords/blogs
Blog Park address: "the history of living in the big front-end" original blog directory
Huawei cloud community Address: [you want the front Daguai upgrade guide]
A. Requirements Analysis
Providing an embedded program to another function unit pages, most pages are used pages independent function, individual pages with the left side bar (corresponding to the integrated form of pages 3-4), as defined in the Resource Locator, after each page is packaged as a single page, the entry html
documents need to customize the name and the script and style files need to be placed under the specified path, address public resources must also be replaced by a special character to invoke the logic of adaptation parent system (such as the following structure application jquery.min.js
path may be {{publicRoot}}/{{publicLib}}/jquery.minjs
). AB assumption that the original project has these two old page, CDE now need to develop these three pages, the directory structure requirements are as follows:
The blue part of the old resources, the green part of the new development needs.
II. Analysis of the original proposal
The original program uses Vue+ElementUI
to develop, build process is basically zero configuration, development efficiency is very high, the page style uniform, but zero configuration build process can only generate SPA
application mode, so the practice of the original program are:
The build process requires a custom amount extracted to
config.js
file unified management, the general form as follows://config.js module.exports = { A:{ publicPath:'{{publicRoot}}/{{publicLib}}' prodFileName:'A.html', entryKey:'public/A', entryPath:'public/A/A.js' }, B:{ //... } //... }
Used in the development of a unified routing file
router.js
, the packaging process inmain.js
reference to the corresponding pageXX.router.spa.js
as routing, while the other pages commented, passing command line parameters when packaging--key=XXX
,key
value is parsed from the packed scriptconfig.js
out packaged in need set parameters, and then the target page packaged as a separate page, other pages, although it also works, but is not involved in packaging.// 入口文件src/main.js import router from './pages/C/router.spa'; //import router from './pages/D/router.spa'; //import router from './pages/E/router.spa';
Above packaging process there have been many problems in use:
- No peeling common dependencies,
vue
andElementUI
can be packaged into every single page, so that each packed outindex.js
almost the size of 1.2MB, this wasted space is not necessary. - Public style does not form a separate file, which makes whenever a style details changed, you need to manually re each page one by one out of the package.
- After increasing the page
main.js
there will be a lot of independent route, if development were cross-page changes, probably inmain.js
the time C in the active route for routing page, when packaged--key
value of the parameter passed it becameD
, this did not cause error, but in fact build results really wrong. - Since the entrance to keep the file
main.js
has not changed, so in different pages package, the results are output indist
the directory, you need to manually address the parent project to match, complicated operation.
III. 3-step multi-page reform
The above problems are actually the original proposal because a multi-page development needs in accordance with the one-page application to achieve caused by the need to build automation project some customization.
Configuration 1. Separation webpack
In the present embodiment the development environment and the main difference is that the final packaged routes may be required due to the development of cross-page development, a single inlet and separate routing is performed when the application needs to output multi-page build production, so the first thing is the original webpack.config.js
file split webpack.base.js
, webpack.dev.js
, webpack.prod.js
three documents, webpack.base.js
environmental undifferentiated configuration, and then build models based on different, use webpack-merge plugin related configuration environment combined with the basic configuration:
/*webpack.base.js示例*/
const argv = require('yargs-parser')(process.argv.slice(2));
const env_short = argv.env.all ? 'all' : argv.p ? 'prod':'dev';
const webpackConfig = require(`./config/webpack.${env_short}`);//根据-p属性加载webpack的dev配置或prod配置
const merge = require('webpack-merge');
//基本配置
const baseConfig = {
//....
}
//输出合并后的配置
module.exports = merge(baseConfig, webpackConfig);
webpack.dev.js
SPA remains set originally developed to meet the demand.
2. pulled out of external references
In this case a large external applications vue
and ElementUI
many developers have been using automation tools scaffolding, and do not realize how these two libraries depend on the introduction of an external project. Public libraries need to pull away webpack
in the configuration of its fill in the external
Configuration item:
module.exports = {
//...
externals:{
vue:'Vue',
'element-ui':'ELEMENT'
},
//...
}
key
The module name referenced value
global corresponds to the introduction of the module name, meaning external configuration item is: Please do not use this module injected into the JS file compiled in, any import the source code appear / require this module statement , set it to retain and rely on a modular manner adapted according to the standard .
Tips:
Vue
When there are as many external dependencies to build the package, in this case because of the usewebpack
were constructed, there is no demand online compilation of templates, so no need to introduce a completeVue
, but only after the introduction of the compressed version contains only the runtimevue.runtime.min.js
can be.- Note that the external import library name, such as the case of the ELEMENT , developers often fill in for their own use in code ElementUI caused by an error when uncertainty names, there is a simple way is to find the resources to see a CDN click, typically beginning codes are
UMD
standard fixed structure, it is easy to see the images (as shown below).
CDN will then address a public library or a local address resource added to index.html
, you can use the template syntax, and then from html-webpack-plugin
passing custom parameters to instantiate the plug:
<!--html文件模板-->
<body>
<div id="app"></div>
<script src="<%= htmlWebpackPlugin.options.vue_path %>"></script>
<script src="<%= htmlWebpackPlugin.options.elementUI_path %>"></script>
<script src="<%= htmlWebpackPlugin.options.tpl_entryPath %>/index.js"></script>
</body>
//webpack.prod.js
module.exports = {
//...
plugins: [
new HtmlWebpackPlugin({
template: 'src/index.html',//生成index.html时依据的模板
filename: '.....',
inject:false,
tpl_entryPath:'....',
vue_path:'.....',
elementUI_path:'.....',
}),
//new BundleAnalyzerPlugin()
],
}
After generating the final package index.html
file is as follows:
<body>
<div id="app"></div>
<script src="{{publicRoot}}/{{publicLib}}/vue.min.js"></script>
<script src="{{publicRoot}}/{{publicLib}}/element-ui.js"></script>
<script src="public/A/A.js"></script>
</body>
If a third party, from a local database, the need /node_modules/element-ui/lib/index.js
and /node_modules/vue/dist/vue.runtime.min.js
two dependent files are copied to lib
the corresponding address in the folder, so that access index.html
time can be in the form of external dependencies of loads it came. Peel style file directly using the plug-in can be completed, webpack4 previous version extract-text-webpack-plugin
, version 4.0 from the consistent use mini-css-extract-plugin
.
3. webpack custom multi-entry
Configure multiple key entry is packaged multi-page applications, due to the presence of nested directories packed result, it is necessary for entry
the key object to be some customization, the path information is directly packaged key
to custom values, while the need to instantiate a plurality of HtmlWebpackPlugin
generating a respective file entry for each index.html
access entry, custom parameters can be passed at instantiation:
//webpack.prod.js
module.exports = {
entry:{
'C/index':'./src/pages/C/C.entry.js',
'DESK/D/index':'./src/pages/D/D.entry.js',
'DESK/E/index':'./src/pages/E/E.entry.js'
}
//...
plugins:[
new HtmlWebpackPlugin({...paramsC}),
new HtmlWebpackPlugin({...paramsD}),
new HtmlWebpackPlugin({...paramsE}),
]
}
Of course, you can entry
or plugins
assembly process of peeling an array to another file, and then direct reference:
Of course, each page of the file entry X.entry.js
corresponding to the old program main.js
portion remaining after the routing information is not enabled is commented remove files, it is sufficient to support every single page to be accessed independently.
IV. Summary
After the above transformation in dist
the structure of demand and output in the directory public
structure under the directory on keeping it, and each page of the index.js
document is also reduced to around 100K. Of course, you can also use node.js
to write some automated scripts, the subsequent replacement process is automated, or continue to webpack
the packaging process is optimized, we will not repeat them.