Node.js 安裝包及源碼下載地址爲:https://nodejs.org/en/download/。javascript
Git 各平臺安裝包下載地址爲:http://git-scm.com/downloadscss
1.node -vhtml
npm -v // 更新:npm update -gvue
npm config set registry https://registry.npm.taobao.org
//設置代理 能夠用npm config get registry/npm info express 驗證
//恢復設置:npm config set registry https://registry.npmjs.org/java
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
$ cnpm -v
//單獨使用node
npm init
// 建立 package.json 文件。以後,還須要建立模塊的入口文件。默認文件名是 index.js。webpack
2.git --version
// git init 保存你的每一次修改,並推送到遠程倉庫(須要設置令牌才能推送,如:github、碼雲 、騰訊雲)git
cnpm install -g vue-cli 或 cnpm update vue-cli
vue -vgithub
vue init webpack demo0720web
//demo儘可能不安裝多餘內容,一鍵搞定: enter
//ps:ESLint(一個javascript代碼檢測工具)、unit tests(單元測試)、Nightwatch(一個e2e用戶界面測試工具)。
//webpack4.0中文文檔:https://github.com/wallstreetcn/webpack-and-spa-guide
//項目文件結構以下:各類插件自行安裝,如markdown、eslint(項目+編輯器)
使用npm init 搭建的項目結構
├── dist 打包輸出目錄,只需部署這個目錄到生產環境
├── package.json 項目配置信息
├── node_modules npm 安裝的依賴包都在這裏面
├── src 咱們的源代碼
│ ├── components 能夠複用的模塊放在這裏面
│ ├── index.html 入口 html
│ ├── index.js 入口 js
│ ├── shared 公共函數庫
│ └── views 頁面放這裏
└── webpack.config.js webpack 配置文件
使用vue-cli搭建的項目結構
. ├── build/ # webpack config files / webpack 配置文件,一般,您不須要觸摸這些文件,除非您想要自定義Webpack加載器,在這種狀況下您應該查看 │ └── ... ├── config/ │ ├── index.js # main project config / 項目主要配置 │ └── ... ├── src/ # 主要的項目開發文件都在這個目錄下: │ ├── main.js # app entry file / 應用入口文件 │ ├── App.vue # main app component / App 父組件 │ ├── components/ # ui components / 可複用的 ui 組件 │ │ └── ... │ ├── assets/ # module assets (processed by webpack) / 模塊資源(通過 webpack 處理,如文件合併,圖片壓縮等) │ │ └── ... │ ├── page/ ## 以頁面爲單位的 .vue 文件 │ │ ├── index.vue ## 一級 router-view,頂部導航欄和左側側邊導航欄 │ │ ├── 404.vue ## 404 頁面 │ │ ├── menu1/ ## 二級 router-view,導航切換後的頁面內容 │ │ │ └── ... │ │ └── menu2/ ## 按照菜單項建立文件夾對文件進行組織管理 │ │ └── ... │ └── router/ │ └── index.js # 路由配置文件 ├── static/ # pure static assets (directly copied) / 純靜態資源(直接拷貝使用,不通過 webpack 處理) ├── .babelrc # babel config ├── .eslintrc.js # eslint config ├── .editorconfig # editor config ├── index.html # index.html template ├── package.json # build scripts and dependencies └── ...
在實際開發中發現,自定義buld文件會帶來很大的收益,如設置通配符來代替絕對路徑的引用、配置eslint動態校驗、less等插件編譯設置、動態構建不一樣環境的開發版本(開發、測試、上線):
(1)build.js
require/export是一種nodeJs(commonJs規範)的依賴注入的方法,import/export是ES6語法,用於引入模塊,在nodeJs中使用的ES6語法最終會使用babel工具(babel-loader)轉化爲ES5
define()
和 require()
的區別是,define()
必需要在回調函數中返回一個值做爲導出的東西,CommoeJS使用require()
不須要導出東西,所以回調函數中不須要返回值(return xxx)
'use strict' require('./check-versions')() //調用版本檢查 process.env.NODE_ENV = 'production' //將環境配置爲生產環境 const ora = require('ora') //npm包 loading插件 const rm = require('rimraf') //npm包 用於刪除文件 const path = require('path')//npm包 文件路徑工具 const chalk = require('chalk')//npm包 在終端輸出帶顏色的文字 const webpack = require('webpack')//引入webpack.js const config = require('../config')//引入配置文件 const webpackConfig = require('./webpack.prod.conf')//引入生產環境配置文件 // 在終端顯示loading效果,並輸出提示 const spinner = ora('building for production...') spinner.start() //先遞歸刪除dist文件再生成新文件,避免冗餘 rm(path.join(config.build.assetsRoot, config.build.assetsSubDirectory), err => { if (err) throw err webpack(webpackConfig, (err, stats) => { spinner.stop() if (err) throw err process.stdout.write(stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false }) + '\n\n') if (stats.hasErrors()) { console.log(chalk.red(' Build failed with errors.\n')) process.exit(1) } console.log(chalk.cyan(' Build complete.\n')) console.log(chalk.yellow( ' Tip: built files are meant to be served over an HTTP server.\n' + ' Opening index.html over file:// won\'t work.\n' )) }) })
(2)check-version.js:檢測node和npm的版本,實現版本依賴
'use strict' const chalk = require('chalk') const semver = require('semver')//檢查版本 const packageConfig = require('../package.json') const shell = require('shelljs')//shelljs 模塊從新包裝了 child_process,調用系統命令更加方便 function exec (cmd) {//返回經過child_process模塊的新建子進程,執行 Unix 系統命令後轉成沒有空格的字符串 return require('child_process').execSync(cmd).toString().trim() } const versionRequirements = [ { name: 'node', currentVersion: semver.clean(process.version),//使用semver格式化版本 versionRequirement: packageConfig.engines.node //獲取package.json中設置的node版本 } ] if (shell.which('npm')) { versionRequirements.push({ name: 'npm', currentVersion: exec('npm --version'),// 自動調用npm --version命令,而且把參數返回給exec函數,從而獲取純淨的版本號 versionRequirement: packageConfig.engines.npm }) } module.exports = function () { const warnings = [] for (let i = 0; i < versionRequirements.length; i++) { const mod = versionRequirements[i] //若版本號不符合package.json文件中指定的版本號,就報錯 if (!semver.satisfies(mod.currentVersion, mod.versionRequirement)) { warnings.push(mod.name + ': ' + chalk.red(mod.currentVersion) + ' should be ' + chalk.green(mod.versionRequirement) ) } } if (warnings.length) { console.log('') console.log(chalk.yellow('To use this template, you must update following to modules:')) console.log() for (let i = 0; i < warnings.length; i++) { const warning = warnings[i] console.log(' ' + warning) } console.log() process.exit(1) } }
(3)utils.js:utils是工具的意思,是一個用來處理css的文件,這個文件包含了三個工具函數:
生成靜態資源的路徑
生成 ExtractTextPlugin對象或loader字符串
生成 style-loader的配置
var path = require('path')// node自帶的文件路徑工具 var config = require('../config')// 配置文件 var ExtractTextPlugin = require('extract-text-webpack-plugin')// 提取css的插件 /** @method assertsPath 生成靜態資源的路徑(判斷開發環境和生產環境,爲config文件中index.js文件中定義assetsSubDirectory) * @param {String} _path 相對於靜態資源文件夾的文件路徑 * @return {String} 靜態資源完整路徑 */ exports.assetsPath = function (_path) { var assetsSubDirectory = process.env.NODE_ENV === 'production' ? config.build.assetsSubDirectory : config.dev.assetsSubDirectory //nodeJs path提供用於處理文件路徑的工具;path.posix提供對路徑方法的POSIX(可移植性操做系統接口)特定實現的訪問(可跨平臺); path.posix.join與path.join同樣,不過老是以 posix 兼容的方式交互 return path.posix.join(assetsSubDirectory, _path) } /**@method cssLoaders 生成處理css的loaders配置,使用css-loader和postcssLoader,經過options.usePostCSS屬性來判斷是否使用postcssLoader中壓縮等方法 * @param {Object} option = {sourceMap: true,// 是否開啓 sourceMapextract: true // 是否提取css}生成配置 * @return {Object} 處理css的loaders配置對象 */ exports.cssLoaders = function (options) { options = options || {} var cssLoader = { loader: 'css-loader', options: { minimize: process.env.NODE_ENV === 'production', sourceMap: options.sourceMap } } /**@method generateLoaders 生成 ExtractTextPlugin對象或loader字符串 * @param {Array} loaders loader名稱數組 * @return {String|Object} ExtractTextPlugin對象或loader字符串 */ function generateLoaders (loader, loaderOptions) { var loaders = [cssLoader] if (loader) { loaders.push({ loader: loader + '-loader', options: Object.assign({}, loaderOptions, { sourceMap: options.sourceMap }) }) } // ExtractTextPlugin提取css(當上面的loaders未能正確引入時,使用vue-style-loader) if (options.extract) {// 生產環境中,默認爲true return ExtractTextPlugin.extract({ use: loaders, fallback: 'vue-style-loader' }) } else {//返回vue-style-loader鏈接loaders的最終值 return ['vue-style-loader'].concat(loaders) } } return { css: generateLoaders(),//須要css-loader 和 vue-style-loader postcss: generateLoaders(),//須要css-loader、postcssLoader 和 vue-style-loader less: generateLoaders('less'),//須要less-loader 和 vue-style-loader sass: generateLoaders('sass', { indentedSyntax: true }),//須要sass-loader 和 vue-style-loader scss: generateLoaders('sass'),//須要sass-loader 和 vue-style-loader stylus: generateLoaders('stylus'),//須要stylus-loader 和 vue-style-loader styl: generateLoaders('stylus')//須要stylus-loader 和 vue-style-loader } } /**@method styleLoaders 生成 style-loader的配置 * @param {Object} options 生成配置 * @return {Array} style-loader的配置 */ exports.styleLoaders = function (options) { var output = [] var loaders = exports.cssLoaders(options) //將各類css,less,sass等綜合在一塊兒得出結果輸出output for (var extension in loaders) { var loader = loaders[extension] output.push({ test: new RegExp('\\.' + extension + '$'), use: loader }) } return output }
(4)vue-loader.conf.js:處理.vue文件,解析這個文件中的每一個語言塊(template、script、style),轉換成js可用的js模塊。
'use strict' const utils = require('./utils') const config = require('../config') const isProduction = process.env.NODE_ENV === 'production' //生產環境,提取css樣式到單獨文件 const sourceMapEnabled = isProduction ? config.build.productionSourceMap : config.dev.cssSourceMap module.exports = { loaders: utils.cssLoaders({ sourceMap: sourceMapEnabled, extract: isProduction }), cssSourceMap: sourceMapEnabled, cacheBusting: config.dev.cacheBusting, //編譯時將「引入路徑」轉換爲require調用,使其可由webpack處理 transformToRequire: { video: ['src', 'poster'], source: 'src', img: 'src', image: 'xlink:href' } }
(5)webpack.base.conf.js:開發、測試、生產環境的公共基礎配置文件,配置輸出環境,配置模塊resolve和插件等
'use strict' const path = require('path')// node自帶的文件路徑工具 const utils = require('./utils')// 工具函數集合 const config = require('../config')// 配置文件 const vueLoaderConfig = require('./vue-loader.conf')// 工具函數集合 /** * 獲取"絕對路徑" * @method resolve * @param {String} dir 相對於本文件的路徑 * @return {String} 絕對路徑 */ function resolve(dir) { return path.join(__dirname, '..', dir) } module.exports = { context: path.resolve(__dirname, '../'), //入口js文件(默認爲單頁面因此只有app一個入口) entry: { app: './src/main.js' }, //配置出口 output: { path: config.build.assetsRoot,//打包編譯的根路徑(dist) filename: '[name].js', publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath//發佈路徑 }, resolve: { extensions: ['.js', '.vue', '.json'],// 自動補全的擴展名 //別名配置 alias: { 'vue$': 'vue/dist/vue.esm.js', '@': resolve('src'),// eg:"src/components" => "@/components" } }, module: { rules: [ //使用vue-loader將vue文件編譯轉換爲js { test: /\.vue$/, loader: 'vue-loader', options: vueLoaderConfig }, //經過babel-loader將ES6編譯壓縮成ES5 { test: /\.js$/, loader: 'babel-loader', include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] }, //使用url-loader處理(圖片、音像、字體),超過10000編譯成base64 { test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('img/[name].[hash:7].[ext]') } }, { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('media/[name].[hash:7].[ext]') } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } ] }, //nodeJs全局變量/模塊,防止webpack注入一些nodeJs的東西到vue中 node: { setImmediate: false, dgram: 'empty', fs: 'empty', net: 'empty', tls: 'empty', child_process: 'empty' } }
(6)webpack.dev.conf.js:webpack配置開發環境中的入口
'use strict' const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge')//webpack-merge實現合併 const path = require('path') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const FriendlyErrorsPlugin = require('friendly-errors-webpack-plugin')//webpack的提示錯誤和日誌信息的插件 const portfinder = require('portfinder')// 查看空閒端口位置,默認狀況下搜索8000這個端口 const HOST = process.env.HOST const PORT = process.env.PORT && Number(process.env.PORT) const devWebpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true }) }, devtool: config.dev.devtool,//調試模式 devServer: { clientLogLevel: 'warning', historyApiFallback: {//使用 HTML5 History API 時, 404 響應替代爲 index.html rewrites: [ { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') }, ], }, hot: true,//熱重載 contentBase: false, // 提供靜態文件訪問 compress: true,//壓縮 host: HOST || config.dev.host, port: PORT || config.dev.port, open: config.dev.autoOpenBrowser,//npm run dev 時自動打開瀏覽器 overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false,// 顯示warning 和 error 信息 publicPath: config.dev.assetsPublicPath, proxy: config.dev.proxyTable,//api代理 quiet: true, //控制檯打印警告和錯誤(用FriendlyErrorsPlugin 爲 true) watchOptions: {// 檢測文件改動 poll: config.dev.poll, } }, plugins: [ new webpack.DefinePlugin({ 'process.env': require('../config/dev.env') }), new webpack.HotModuleReplacementPlugin(),//模塊熱替換插件,修改模塊時不須要刷新頁面 new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update. new webpack.NoEmitOnErrorsPlugin(),//webpack編譯錯誤的時候,中斷打包進程,防止錯誤代碼打包到文件中 // 將打包編譯好的代碼插入index.html new HtmlWebpackPlugin({ filename: 'index.html', template: 'index.html', inject: true }), // 提取static assets 中css 複製到dist/static文件 new CopyWebpackPlugin([ { from: path.resolve(__dirname, '../static'), to: config.dev.assetsSubDirectory, ignore: ['.*']//忽略.*的文件 } ]) ] }) module.exports = new Promise((resolve, reject) => { portfinder.basePort = process.env.PORT || config.dev.port portfinder.getPort((err, port) => { //查找端口號 if (err) { reject(err) } else { //端口被佔用時就從新設置evn和devServer的端口 process.env.PORT = port devWebpackConfig.devServer.port = port // npm run dev成功的友情提示 devWebpackConfig.plugins.push(new FriendlyErrorsPlugin({ compilationSuccessInfo: { messages: [`Your application is running here: http://${devWebpackConfig.devServer.host}:${port}`], }, onErrors: config.dev.notifyOnErrors ? utils.createNotifierCallback() : undefined })) resolve(devWebpackConfig) } }) })
(7)webpack.dev.prod.js:webpack配置生產環境中的入口
'use strict' const path = require('path') const utils = require('./utils') const webpack = require('webpack') const config = require('../config') const merge = require('webpack-merge') const baseWebpackConfig = require('./webpack.base.conf') const CopyWebpackPlugin = require('copy-webpack-plugin') const HtmlWebpackPlugin = require('html-webpack-plugin') const ExtractTextPlugin = require('extract-text-webpack-plugin') const OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin') const UglifyJsPlugin = require('uglifyjs-webpack-plugin') const env = require('../config/prod.env') const webpackConfig = merge(baseWebpackConfig, { module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true, usePostCSS: true }) }, devtool: config.build.productionSourceMap ? config.build.devtool : false,//是否開啓調試模式 output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') }, plugins: [ new webpack.DefinePlugin({ 'process.env': env }), new UglifyJsPlugin({//壓縮js uglifyOptions: { compress: { warnings: false } }, sourceMap: config.build.productionSourceMap, parallel: true }), new ExtractTextPlugin({//提取靜態文件,減小請求 filename: utils.assetsPath('css/[name].[contenthash].css'), allChunks: true, }), new OptimizeCSSPlugin({//提取優化壓縮後(刪除來自不一樣組件的冗餘代碼)的css cssProcessorOptions: config.build.productionSourceMap ? { safe: true, map: { inline: false } } : { safe: true } }), new HtmlWebpackPlugin({ //html打包壓縮到index.html filename: config.build.index, template: 'index.html', inject: true, minify: { removeComments: true,//刪除註釋 collapseWhitespace: true,//刪除空格 removeAttributeQuotes: true//刪除屬性的引號 }, chunksSortMode: 'dependency'//模塊排序,按照咱們須要的順序排序 }), new webpack.HashedModuleIdsPlugin(), new webpack.optimize.ModuleConcatenationPlugin(), new webpack.optimize.CommonsChunkPlugin({ // node_modules中的任何所需模塊都提取到vendor name: 'vendor', minChunks (module) { return ( module.resource && /\.js$/.test(module.resource) && module.resource.indexOf( path.join(__dirname, '../node_modules') ) === 0 ) } }), new webpack.optimize.CommonsChunkPlugin({ name: 'manifest', minChunks: Infinity }), new webpack.optimize.CommonsChunkPlugin({ name: 'app', async: 'vendor-async', children: true, minChunks: 3 }), new CopyWebpackPlugin([//複製static中的靜態資源(默認到dist裏面) { from: path.resolve(__dirname, '../static'), to: config.build.assetsSubDirectory, ignore: ['.*'] } ]) ] }) if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ asset: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) ) } if (config.build.bundleAnalyzerReport) { const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) } module.exports = webpackConfig
(1) dev.env.js和prod.env.js:分別配置:開發環境和生產環境。這個能夠根據公司業務結合後端需求配置須要區分開發環境和測試環境的屬性
// dev.env,js 'use strict' const merge = require('webpack-merge') //合併對象插件 const prodEnv = require('./prod.env') module.exports = merge(prodEnv, { NODE_ENV: '"development"' //訪問(獲取值)時直接用:process.env.xxx }) //prod.env.js 'use strict' module.exports = { NODE_ENV: '"production"' //*注意屬性值要用「‘’」雙層引住 }
webpack-merge用於實現合併相似於ES6的對象合併Object.assign()
process(進程)是nodejs的一個全局變量,process.env 屬性返回一個用戶環境信息的對象
(2)index.js配置解析:
'use strict'; const path = require('path'); module.exports = { // ===================開發環境配置 dev: { assetsSubDirectory: 'static',//靜態資源文件夾(通常存放css、js、image等文件) assetsPublicPath: '/',//根目錄 proxyTable: {},//配置API代理,可利用該屬性解決跨域的問題 host: 'localhost', // 能夠被 process.env.HOST 覆蓋 port: 3030, // 能夠被 process.env.PORT 覆蓋 autoOpenBrowser: true,//編譯後自動打開瀏覽器頁面 http://localhost:3030/("port + host",默認"false"),設置路由重定向自動打開您的默認頁面 errorOverlay: true,//瀏覽器錯誤提示 notifyOnErrors: true,//跨平臺錯誤提示 poll: false, //webpack提供的使用文件系統(file system)獲取文件改動的通知devServer.watchOptions(監控文件改動) devtool: 'cheap-module-eval-source-map',//webpack提供的用來調試的模式,有多個不一樣值表明不一樣的調試模式 cacheBusting: true,// 配合devtool的配置,當給文件名插入新的hash致使清除緩存時是否生成source-map cssSourceMap: true //記錄代碼壓縮前的位置信息,當產生錯誤時直接定位到未壓縮前的位置,方便調試 }, // ========================生產環境配置 build: { index: path.resolve(__dirname, '../dist/index.html'),//編譯後"首頁面"生成的絕對路徑和名字 assetsRoot: path.resolve(__dirname, '../dist'),//打包編譯的根路徑(默認dist,存放打包壓縮後的代碼) assetsSubDirectory: 'static',//靜態資源文件夾(通常存放css、js、image等文件) assetsPublicPath: '/',//發佈的根目錄(dist文件夾所在路徑) productionSourceMap: true,//是否開啓source-map devtool: '#source-map',//(詳細參見:https://webpack.docschina.org/configuration/devtool) productionGzip: false,//是否壓縮 productionGzipExtensions: ['js', 'css'],//unit的gzip命令用來壓縮文件(gzip模式下須要壓縮的文件的擴展名有js和css) bundleAnalyzerReport: process.env.npm_config_report //是否開啓打包後的分析報告 } };
咱們須要在src文件夾中開發代碼,打包時webpack會根據build中的規則(build規則依賴於config中的配置)將src打包壓縮到dist文件夾在瀏覽器中運行
(1)assets文件:用於存放靜態資源(css、image),assets打包時路徑會通過webpack中的file-loader編譯(所以,assets須要使用絕對路徑)成js
(2)components文件夾:用來存放 .vue 組件(實現複用等功能,如:過濾器,列表項等)
(3)router文件夾:在router/index.js文件中配置頁面路由
(4)App.vue:是整個項目的主組件,全部頁面都是經過使用<router-view/>開放入口在App.vue下進行切換的(全部的路由都是App.vue的子組件)
(5)main.js:入口js文件(全局js,你能夠在這裏:初始化vue實例、require/import須要的插件、注入router路由、引入store狀態管理)
webpack默認存放靜態資源(css、image)的文件夾,與assets不一樣的是:static在打包時會直接複製一個同名文件夾到dist文件夾裏(不會通過編譯,可以使用相對路徑)
(1).babelrc:瀏覽器解析的兼容配置,該文件主要是對預設(presets)和插件(plugins)進行配置,所以不一樣的轉譯器做用不一樣的配置項,大體可分爲:語法轉義器、補丁轉義器、sx和flow插件
(2).editorconfig:用於配置代碼格式(配合代碼檢查工具使用,如:ESLint,團隊開發時可統一代碼風格),這裏配置的代碼規範規則優先級高於編輯器默認的代碼格式化規則 。
(3).gitignore:配置git提交時須要忽略的文件
(4)postcssrc.js: autoprefixer(自動補全css樣式的瀏覽器前綴);postcss-import(@import引入語法)、CSS Modules(規定樣式做用域)
(5)index.html:項目入口頁面,編譯以後全部代碼將插入到這來
(6)package.json:npm的配置文件(npm install根據package.json下載對應版本的安裝包)
(7)package.lock.json:npm install(安裝)時鎖定各包的版本號
(8)README.md:項目使用說明
參考:
https://yq.aliyun.com/articles/646536