NEXT 中文文檔地址!css
- next.js 只有服務端使用的包須要作單獨處理,無需打包到項目中,可使用@zeit/next-bundle-analyzer觀察代碼。
- Router.beforePopState() 截斷Router操做的設置只有在客戶端生效(需在componentDidMount中設置)且進入此函數中的方法只有Router棧中有值的時候才能夠!
- next.js 中設置絕對路徑的方法是在next.config.js中wepack方法中的config參數增長配置。
- next.js 中配置自定義接口可使用自定義啓動參數,建立 server.js 經過 node server.js 啓動。
- next.js 支持IE11和各主流瀏覽器 IE11之內的IE版本不支持。
- Link 標籤passHref屬性能夠強制給子元素傳遞href屬性,有利於SEO優化。
- windows 不支持 NODE_ENV=development的設置方式 導入 cross-env 而後運行時在前面添加 cross-env 便可解決。
- webpack 配置自定義的時候覆蓋配置須要繼承本有的配置,不然會使 next 解析錯誤(analysis error)。
module.exports = { // ... other next.js config return { webpack: config => { config.resolve.alias = { ...(config.resolve.alias || {}), // custom webpack aliases } return config } } }
- null-loader 加載器的一個用途是關閉依賴項導入的模塊。 例如,你的項目依賴於導入你不須要的polyfill的ES6庫,因這裏刪除它將致使不會丟失功能。 測試polyfill的路徑,它將不包含在你的包中。
- next.js 引入antd @zeit/next-css babel-plugin-import 按需加載沒法正確編譯css文件須要在next.config.js中配置服務端渲染方可。
const withCss = require('@zeit/next-css') module.exports = withCss({ webpack: (config, { isServer }) => { if (isServer) { const antStyles = /antd\/.*?\/style\/css.*?/ const origExternals = [...config.externals] config.externals = [ (context, request, callback) => { if (request.match(antStyles)) return callback() if (typeof origExternals[0] === 'function') { origExternals[0](context, request, callback) } else { callback() } }, ...(typeof origExternals[0] === 'function' ? [] : origExternals), ] config.module.rules.unshift({ test: antStyles, use: 'null-loader', }) } return config }, })
- next.js 引入@zeit/less須要將antd的按需加載style改成true。
- postCss/postCss-use 使用方法:
module.exports = { plugins: [ require('postcss-use')({ // allow autoprefixer modules: [ 'autoprefixer' ] }) ] }
- analysis && antd 3.x.x version icon 異步加載(next配置方案) && moment 語言包打包優化。
moment 語言包使用 webpack.IgnorePlugin 會把全部語言過濾掉,因此須要使用 webpack.ContextReplacementPlugin 來指定打包篩選方案,而後單獨引入所需moment語言包便可!const webpack = require('webpack') const withSass = require('@zeit/next-sass'); const withBundleAnalyzer = require("@zeit/next-bundle-analyzer") module.exports = withBundleAnalyzer(withSass({ analyzeServer: ["server", "both"].includes(process.env.BUNDLE_ANALYZE), analyzeBrowser: ["browser", "both"].includes(process.env.BUNDLE_ANALYZE), bundleAnalyzerConfig: { server: { analyzerMode: 'static', reportFilename: '../../bundles/server.html' }, browser: { analyzerMode: 'static', reportFilename: '../bundles/client.html' } }, webpack: (config, { dev }) => { config.module.rules.push( { test: /\.(ttf|eot|svg|png|jpg|gif|ico)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader', options: { name: '../../../[path][name].[ext]' } }, { test: /\.(css|scss)/, loader: 'emit-file-loader', options: { name: 'dist/[path][name].[ext]' } }, { test: /\.css$/, use: ['babel-loader', 'raw-loader', 'postcss-loader'] } //, { // test: /\.s(a|c)ss$/, // use: ['babel-loader', 'raw-loader', 'postcss-loader', // { // loader: 'sass-loader', // options: { // includePaths: ['styles', 'node_modules'] // .map((d) => path.join(__dirname, d)) // .map((g) => glob.sync(g)) // .reduce((a, c) => a.concat(c), []) // } // } // ] // } ) !dev && config.module.rules.push({ loader:'webpack-ant-icon-loader', enforce: 'pre', options:{ chunkName:'antd-icons' }, include: [ require.resolve('@ant-design/icons/lib/dist.js') ] }) !dev && config.plugins.push( // 阻止生成與正則表達式或過濾器函數匹配的模塊import或require調用 // new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/), // 引入未知包的時候webpack會推斷出directory的包,而後所有打包進入bundle,此條配置容許覆蓋推斷信息,更加精確的配置打包數據 new webpack.ContextReplacementPlugin( /moment[\\\/]locale$/, /^\.\/(th)\.js$/ ) // 加到next/webpack.js配置中 // new webpack.optimize.CommonsChunkPlugin({ // // name: 'icons', // // filename: 'icons.js', // minChunks: function (module, count) { // if (dev || (module.resource && module.resource.includes('icons'))) { // return false; // } // } // }), ) return config }, // exportPathMap: function (defaultPathMap) { // return { // '/': { page: '/' }, // } // } }))
- 針對低版本next使用的webpack3配置中使用webpack-icons-loader須要單獨配置以及處理export以後的文件索引,方案爲:
var fs = require('fs') var path = require('path') function editWebpack (srcPath) { let prefix = path.extname(srcPath) // 過濾除js和html的文件 if (prefix === '.js') { const data = fs.readFileSync(srcPath, 'utf8'); let line = data.split('\n') let len = line.length let newLines = '' let isEdit = false for (let i = 0; i < len; i++) { if (i > 347 && i < 350) { let isFind = ~line[i].indexOf('(dev)') !isEdit && (isEdit = isFind) line[i] = isFind ? ' if (dev || (module.resource && module.resource.includes(\'icons\') && count >= 0)) {' : line[i] } newLines += line[i] + (i !== len - 1 ? '\n' : '') } fs.writeFileSync(srcPath, newLines, 'utf8'); isEdit && console.log('webpack update success:' + srcPath + '\n') } } function editIcons (srcPath, tarPath) { let prefix = path.extname(srcPath) // 過濾除js和html的文件 if (prefix === '.js') { const data = fs.readFileSync(srcPath, 'utf8'); fs.writeFileSync(tarPath, data, 'utf8') console.log('@ant-design update success:' + tarPath + '\n') } } editWebpack('./node_modules/next/dist/server/build/webpack.js') editIcons('./static/font/dist.js', './node_modules/@ant-design/icons/lib/dist.js')
var fs = require('fs') var path = require('path') function findFolder (srcDir, tarDir) { // 讀取當前路徑下的全部目錄和文件,返回字符串數組 fs.readdir(srcDir, function (err, files) { files.forEach(function (file) { if (!~file.indexOf('antd-icons')) return var srcPath = path.join(srcDir, file) var tarPath = path.join(tarDir, file) fs.stat(srcPath, function (err, stats) { !stats.isDirectory() && copyFile(srcPath, tarPath) }) }) }) } function copyFile(srcPath, tarPath) { // 建立字節讀取流 var rs = fs.createReadStream(srcPath) rs.on('error', function (err) { if (err) { console.log('read error', srcPath) } }) // 建立字節寫入流 var ws = fs.createWriteStream(tarPath) ws.on('error', function (err) { if (err) { console.log('write error', tarPath) } }) ws.on('close', function (ex) { }) rs.pipe(ws) console.log('ant-icons move success:' + srcPath + '\n') } findFolder('./.next/', './out/_next/webpack/')