I'm trying to deploy the following starter kit on Heroku. However, when I try to start it, it fails :(
Error:
Error R10 (Boot timeout) -> Web process failed to bind to $PORT within 60 seconds of launch
I did not find anywhere to configure or set the port. It's launching on 8080 however it still fails.
Browser-sync-server:
/**
* Start browserSync server
*/
'use strict';
const fs = require('fs');
module.exports = function(options) {
return () => {
// If index.html exist - open it, else show folder
let listDirectory = fs.existsSync(options.mainHtml) ? false : true;
options.browserSync.init({
notify: false,
server: {
baseDir: './',
directory: listDirectory
},
snippetOptions: {
// Provide a custom Regex for inserting the snippet
rule: {
match: /$/i,
fn: (snippet, match) => snippet + match
}
},
port: 8080
});
};
};
Package.json:
{
"name": "Demo-app",
"version": "2.3.2",
"description": "Demo Project",
"repository": {
"type": "git",
},
"keywords": [
"starte",
"markup",
"JustCoded",
"jc"
],
"author": "JustCoded",
"license": "MIT",
"bugs": {
},
"devDependencies": {
"#babel/core": "^7.5.5",
"#babel/preset-env": "^7.5.5",
"babelify": "^10.0.0",
"browser-sync": "^2.18.0",
"browserify": "^16.5.0",
"del": "^3.0.0",
"eslint-config-airbnb-base": "^14.0.0",
"eslint-plugin-import": "^2.14.0",
"files-exist": "^1.1.0",
"gulp": "^4.0.0",
"gulp-autoprefixer": "^4.0.0",
"gulp-concat": "^2.6.1",
"gulp-cssimport": "^5.0.0",
"gulp-cssnano": "^2.1.2",
"gulp-debug": "^3.1.0",
"gulp-eslint": "^5.0.0",
"gulp-file-include": "^2.0.1",
"gulp-group-css-media-queries": "^1.2.0",
"gulp-htmlhint": "^0.3.1",
"gulp-if": "^2.0.2",
"gulp-imagemin": "^4.1.0",
"gulp-newer": "^1.3.0",
"gulp-notify": "^3.0.0",
"gulp-rename": "^1.2.2",
"gulp-sass": "^4.0.2",
"gulp-sourcemaps": "^2.4.1",
"gulp-uglify": "^3.0.0",
"htmlhint-stylish": "^1.0.3",
"node-notifier": "^5.0.2",
"path": "^0.12.7",
"vinyl-source-stream": "^2.0.0"
},
"engines": {
"node": ">=6.0.0"
},
"scripts": {
"test": "gulp build",
"production": "gulp build",
"start": "gulp"
},
"dependencies": {
"include-media": "^1.4.9",
"jquery": "^3.3.1",
"normalize.css": "^5.0.0"
}
}
Gulpfile:
(() => {
'use strict';
const cfg = require('./gulp-config.js'),
gulp = require('gulp'),
del = require('del'),
path = require('path'),
notifier = require('node-notifier'),
gutil = require('gulp-util'),
browserSync = require('browser-sync').create();
/**
* Require gulp task from file
* #param {string} taskName Task name
* #param {String} path Path to task file
* #param {Object} options Options for task
* #param {Array} dependencies Task dependencies
*/
function requireTask(taskName, path, options, dependencies) {
let settings = options || {};
const taskFunction = function (callback) {
if (settings.checkProduction) {
settings.isProduction = process.argv[process.argv.length - 1] === 'build';
}
let task = require(path + taskName + '.js').call(this, settings);
return task(callback);
};
settings.taskName = taskName;
if (!Array.isArray(dependencies)) {
gulp.task(taskName, taskFunction);
} else if (dependencies.length === 1) {
gulp.task(taskName, gulp.series(dependencies[0], taskFunction));
} else {
gulp.task(taskName, gulp.series(dependencies, taskFunction));
}
}
/**
* Remove image(s) from build folder if corresponding
* images were deleted from source folder
* #param {Object} event Event object
* #param {String} src Name of the source folder
* #param {String} dest Name of the destination folder
*/
function deleteFile(file, src, dest) {
let fileName = file.path.toString().split('/').pop();
let fileEventWord = file.event == 'unlink' ? 'deleted' : file.event;
let filePathFromSrc = path.relative(path.resolve(src), file.path);
let destFilePath = path.resolve(dest, filePathFromSrc);
try {
del.sync(destFilePath);
console.log(` \u{1b}[32m${fileEventWord}: ${fileName}\u{1b}[0m`);
} catch (error) {
console.log(` \u{1b}[31mFile has already deleted\u{1b}[0m`);
}
}
/**
* Show error in console
* #param {String} prefix Title of the error
* #param {String} err Error message
*/
function showError(prefix, err) {
gutil.log(gutil.colors.white.bgRed(' ' + prefix + ' '), gutil.colors.white.bgBlue(' ' + err.message + ' '));
notifier.notify({
title: prefix,
message: err.message
});
this.emit('end');
}
/**
* template HTML
*/
requireTask(`${cfg.task.fileInclude}`, `./${cfg.folder.tasks}/`, {
templates: cfg.fileInclude.templates,
dest: cfg.fileInclude.dest
});
/**
* Hint HTML
*/
requireTask(`${cfg.task.htmlHint}`, `./${cfg.folder.tasks}/`);
/**
* Lint ES
*/
requireTask(`${cfg.task.esLint}`, `./${cfg.folder.tasks}/`, {
src: cfg.folder.src
});
/**
* Build custom js
*/
requireTask(`${cfg.task.buildCustomJs}`, `./${cfg.folder.tasks}/`, {
src: cfg.folder.src,
dest: cfg.folder.build,
mainJs: cfg.file.mainJs,
checkProduction: true,
showError: showError
});
/**
* Build js vendor (concatenate vendors array)
*/
requireTask(`${cfg.task.buildJsVendors}`, `./${cfg.folder.tasks}/`, {
src: cfg.folder.src,
dest: cfg.folder.build,
vendorJs: cfg.file.vendorJs,
vendorJsMin: cfg.file.vendorJsMin
});
/**
* Build styles for application from SASS
*/
requireTask(`${cfg.task.buildSass}`, `./${cfg.folder.tasks}/`, {
src: cfg.folder.src,
dest: cfg.folder.build,
mainScss: cfg.file.mainScss,
mainScssMin: cfg.file.mainScssMin,
versions: cfg.autoprefixer.versions,
checkProduction: true,
showError: showError
});
/**
* Compile scss files listed in the config
*/
requireTask(`${cfg.task.buildSassFiles}`, `./${cfg.folder.tasks}/`, {
sassFilesInfo: cfg.getPathesForSassCompiling(),
dest: cfg.folder.build,
versions: cfg.autoprefixer.versions,
showError: showError
});
/**
* Build styles for vendor from SASS
*/
requireTask(`${cfg.task.buildStylesVendors}`, `./${cfg.folder.tasks}/`, {
src: cfg.folder.src,
dest: cfg.folder.build,
vendorScss: cfg.file.vendorScss,
vendorScssMin: cfg.file.vendorScssMin,
showError: showError
});
/**
* Minify images
*/
requireTask(`${cfg.task.imageMin}`, `./${cfg.folder.tasks}/`, {
src: cfg.folder.src,
dest: cfg.folder.build
});
/**
* Clean build folder
*/
requireTask(`${cfg.task.cleanBuild}`, `./${cfg.folder.tasks}/`, {
src: cfg.folder.build
});
/**
* Clean production folder
*/
requireTask(`${cfg.task.cleanProd}`, `./${cfg.folder.tasks}/`, {
src: cfg.folder.prod
});
/**
* Copy folders to the build folder
*/
requireTask(`${cfg.task.copyFolders}`, `./${cfg.folder.tasks}/`, {
dest: cfg.folder.build,
foldersToCopy: cfg.getPathesToCopy()
});
/**
* Copy folders to the production folder
*/
requireTask(`${cfg.task.copyFoldersProduction}`, `./${cfg.folder.tasks}/`, {
dest: cfg.folder.prod,
foldersToCopy: cfg.getPathesToCopyForProduction()
});
/**
* Start browserSync server
*/
requireTask(`${cfg.task.browserSync}`, `./${cfg.folder.tasks}/`, {
mainHtml: cfg.file.mainHtml,
browserSync: browserSync
});
/**
* Watch for file changes
*/
requireTask(`${cfg.task.watch}`, `./${cfg.folder.tasks}/`, {
sassFilesInfo: cfg.getPathesForSassCompiling(),
src: cfg.folder.src,
templates: cfg.folder.templates,
dest: cfg.folder.build,
imageExtensions: cfg.imageExtensions,
browserSync: browserSync,
deleteFile: deleteFile,
tasks: {
buildSassFiles: cfg.task.buildSassFiles,
buildCustomJs: cfg.task.buildCustomJs,
buildSass: cfg.task.buildSass,
esLint: cfg.task.esLint,
fileInclude: cfg.task.fileInclude,
htmlHint: cfg.task.htmlHint,
imageMin: cfg.task.imageMin
}
}, false);
/**
* Default Gulp task
*/
gulp.task('default', gulp.series(
cfg.task.cleanBuild,
gulp.parallel(
cfg.task.buildCustomJs,
cfg.task.buildJsVendors,
cfg.task.buildSass,
cfg.task.buildSassFiles,
cfg.task.buildStylesVendors,
cfg.task.fileInclude,
cfg.task.htmlHint,
cfg.task.esLint,
cfg.task.imageMin
),
cfg.task.copyFolders,
gulp.parallel(
cfg.task.browserSync,
cfg.task.watch
)
));
/**
* Creating production folder without unnecessary files
*/
gulp.task('build', gulp.series(
gulp.parallel(
cfg.task.cleanProd,
cfg.task.cleanBuild
),
gulp.parallel(
cfg.task.buildCustomJs,
cfg.task.buildJsVendors,
cfg.task.buildSass,
cfg.task.buildSassFiles,
cfg.task.buildStylesVendors,
cfg.task.fileInclude,
cfg.task.htmlHint,
cfg.task.esLint,
cfg.task.imageMin
),
cfg.task.copyFolders,
cfg.task.copyFoldersProduction
), true);
})();
It's got some issue with Timeout with the binding of the port.
I've added "preinstall": "npm install -g gulp" and
My Procfile shows the following as well:
web: gulp
Can someone help me why it's failing? I really want to deploy this project on Heroku and would very much appreciate any help to solve!
There is no way on the project to bind the port.
Using process.env.PORT || 8080 instead of just 8080 solved my issue. Heroku likes it this way!
Related
I'm trying to run npm run development, but I got a typescript error here
let { Chunks } = require('../Chunks');
let File = require('../File');
let VueVersion = require('../VueVersion');
let AppendVueStylesPlugin = require('../webpackPlugins/Css/AppendVueStylesPlugin');
/** #typedef {import("vue").VueLoaderOptions} VueLoaderOptions */
class Vue {
/**
* Create a new component instance.
*/
constructor() {
this.chunks = Chunks.instance();
}
/**
* Register the component.
*
* #param {object} options
* #param {number} [options.version] Which version of Vue to support. Detected automatically if not given.
* #param {string|null} [options.globalStyles] A file to include w/ every vue style block.
* #param {boolean|string} [options.extractStyles] Whether or not to extract vue styles. If given a string the name of the file to extract to.
* #param {VueLoaderOptions} [options.options] Options to pass to Vue Loader
*/
register(options = {}) {
if (
arguments.length === 2 &&
typeof arguments[0] === 'string' &&
typeof arguments[1] === 'string'
) {
throw new Error(
'mix.vue() is a feature flag. Use mix.js(source, destination).vue() instead'
);
}
this.version = VueVersion.detect(options.version);
this.options = Object.assign(
{
options: null,
globalStyles: null,
extractStyles: false
},
options
);
Mix.globalStyles = this.options.globalStyles;
Mix.extractingStyles = !!this.options.extractStyles;
}
/**
* Required dependencies for the component.
*/
dependencies() {
this.requiresReload = true;
let dependencies = [
this.version === 2 ? 'vue-template-compiler' : '#vue/compiler-sfc',
this.version === 2 ? 'vue-loader#^15.9.5' : 'vue-loader#^16.1.0'
];
if (this.options.extractStyles && this.options.globalStyles) {
dependencies.push('sass-resources-loader');
}
return dependencies;
}
/**
* Override the generated webpack configuration.
*
* #param {Object} webpackConfig
*/
webpackConfig(webpackConfig) {
// push -> unshift to combat vue loader webpack 5 bug
webpackConfig.module.rules.unshift({
test: /\.vue$/,
use: [
{
loader: this._mix.resolve('vue-loader'),
options: this.options.options || Config.vue || {}
}
]
});
// Alias Vue to its ESM build if the user has not already given an alias
webpackConfig.resolve.alias = webpackConfig.resolve.alias || {};
if (!webpackConfig.resolve.alias['vue$']) {
webpackConfig.resolve.alias['vue$'] = this.aliasPath();
}
webpackConfig.resolve.extensions.push('.vue');
this.updateChunks();
}
aliasPath() {
if (this.version === 2) {
return this.options.runtimeOnly
? 'vue/dist/vue.runtime.esm.js'
: 'vue/dist/vue.esm.js';
}
return this.options.runtimeOnly
? 'vue/dist/vue.runtime.esm-bundler.js'
: 'vue/dist/vue.esm-bundler.js';
}
/**
* webpack plugins to be appended to the master config.
*/
webpackPlugins() {
let { VueLoaderPlugin } = require(this._mix.resolve('vue-loader'));
return [new VueLoaderPlugin(), new AppendVueStylesPlugin()];
}
/**a
* Update CSS chunks to extract vue styles
*/
updateChunks() {
if (this.options.extractStyles === false) {
return;
}
this.chunks.add(
'styles-vue',
this.styleChunkName(),
[/.vue$/, module => module.type === 'css/mini-extract'],
{
chunks: 'all',
enforce: true,
type: 'css/mini-extract'
}
);
}
/**
* Get the name of the style chunk.
*
* #returns {string}
*/
styleChunkName() {
// If the user set extractStyles: true, we'll try
// to append the Vue styles to an existing CSS chunk.
if (this.options.extractStyles === true) {
let chunk = this.chunks.find((chunk, id) => id.startsWith('styles-'));
if (chunk) {
return chunk.name;
}
}
return this.extractFile().relativePathWithoutExtension();
}
/**
* Get a new File instance for the extracted file.
*
* #returns {File}
*/
extractFile() {
return new File(this.extractFileName());
}
/**
* Determine the extract file name.
*
* #return {string}
*/
extractFileName() {
let fileName =
typeof this.options.extractStyles === 'string'
? this.options.extractStyles
: '/css/vue-styles.css';
return fileName.replace(Config.publicPath, '').replace(/^\//, '');
}
}
module.exports = Vue;
**package.json
{
"private": true,
"scripts": {
"development": "mix",
"hot": "mix watch --hot",
"production": "mix --production",
"watch": "mix watch",
"watch-poll": "mix watch -- --watch-options-poll=1000"
},
"dependencies": {
"#chenfengyuan/vue-countdown": "^1.1.5",
"#mdi/light-font": "^0.2.63",
"#types/ziggy-js": "^0.9.0",
"#vue/cli-service": "^5.0.4",
"axios": "^0.21.1",
"dotenv": "^16.0.0",
"eslint": "^7.18.0",
"laravel-echo": "^1.10.0",
"lottie-player-vue": "0.0.16",
"object-to-formdata": "^4.1.0",
"pusher-js": "^7.0.2",
"qrcode": "^1.5.0",
"read-excel-file": "^5.2.28",
"sweetalert2": "^9.17.2",
"v-money": "^0.8.1",
"vee-validate": "^2.2.15",
"vform": "^1.0.1",
"vue-axios": "^2.1.5",
"vue-cli": "^2.9.6",
"vue-countdown": "^1.0.4",
"vue-excel-xlsx": "^1.2.2",
"vue-moment": "^4.1.0",
"vue-qrcode-component": "^2.1.1",
"vue-resource": "^1.5.3",
"vue-sessionstorage": "^1.0.0",
"vue-social-auth": "^1.4.9",
"vue-socket.io": "^3.0.10",
"vue2-storage": "^5.0.0",
"vuedraggable": "^2.24.3",
"vuetify": "^2.6.0",
"vuex": "^3.6.2",
"vuex-map-fields": "^1.4.1",
"ziggy": "^2.4.0",
"ziggy-js": "^1.4.3"
},
"devDependencies": {
"#fortawesome/fontawesome-free": "^5.12.0",
"#inertiajs/inertia": "^0.11.0",
"#inertiajs/inertia-vue": "^0.8.0",
"#inertiajs/progress": "^0.2.7",
"#mdi/font": "^4.9.95",
"#mdi/js": "^5.9.55",
"#nuxtjs/vuetify": "^1.12.3",
"#popperjs/core": "^2.10.2",
"bootstrap": "^5.1.3",
"browser-sync": "^2.26.13",
"browser-sync-webpack-plugin": "^2.3.0",
"cross-env": "^7.0.3",
"deepmerge": "^4.2.2",
"eslint-plugin-import": "^2.19.1",
"eslint-plugin-vue": "^7.5.0",
"font-awesome": "^4.7.0",
"laravel-mix": "6.0.6",
"lodash": "^4.17.20",
"material-design-icons-iconfont": "^6.4.1",
"resolve-url-loader": "^3.1.2",
"roboto-fontface": "^0.10.0",
"sass": "~1.32",
"sass-loader": "^11.1.1",
"vue": "^2.6.12",
"vue-cli-plugin-vuetify": "~2.5.8",
"vue-loader": "^14.2.4",
"vue-template-compiler": "^2.7.14",
"vuetify": "^2.4.2",
"vuetify-loader": "^1.7.0",
"webpack": "^5.75.0",
"webpack-cli": "^5.0.1"
}
}
**
I dont know why I got this error.
I'm new to Vue.js, can someone enlighten me to how to use and continue other's project from scratch ? I got a lot of problems, such as the Vue code not showing changes in the application in my localhost.
My "older" web application uses Grunt and Webpack, but I am wondering if I can remove Grunt completely and still have the same functionality with just Webpack? Or should I replace Grunt with another technology? I've noticed grunt development slow to a crawl, and as new security warnings arise, I am having difficulty upgrading packages.
Below is my grunt file which performs a few basic tasks and allows me to run some very handy commands like "grunt dev" (for packaging dev bundle), "grunt dev-watch" (for packaging and watching for changed files), and "grunt prod" (for production bundle). Additionally, I use maven to build my web application, so I can define these commands from within the pom.xml depending on the build profile (development vs production)
Below: Grunt file, Webpack (common), and Webpack (dev)
gruntfile.js
/**
* Grunt Settings
*
* Contains settings for Grunt tasks that allow for development and production environments
*
* Usage (in bash shell, /webapp directory):
* grunt dev
* grunt dev-watch
* grunt prod
*/
// Define webpack configuration files
const webpackConfig_dev = require('./webpack.dev.js');
const webpackConfig_prod = require('./webpack.prod.js');
module.exports = function(grunt) {
let baseDir = ".";
// Set fileVersion from command line arguments
let fileVersion = grunt.option('fileVersion');
if (typeof fileVersion === 'undefined') {
fileVersion = 'dev';
}
fileVersion = fileVersion.trim();
grunt.initConfig({
// Identify which packages to load
pkg: grunt.file.readJSON('package.json'),
// Remove old files
clean: {
build: {
src: [
// js files
baseDir + '/js/dist',
// css files
baseDir + '/styles/*.css',
baseDir + '/styles/*.map',
]
}
},
// Crunch style files (eg *.scss)
sass: {
options:{
implementation: require('node-sass'),
sourceMap: true,
outputStyle: 'expanded'
},
dist: {
files: [{
src: baseDir + '/styles/main.scss',
dest: baseDir + '/styles/main.' + fileVersion + '.css',
}]
}
},
// Modifications after main.css is created
postcss: {
options: {
map: true,
processors: [
require('autoprefixer')
]
},
dist: {
src: baseDir + '/styles/main.' + fileVersion + '.css'
}
},
// Copy jquery external library to the dist/ folder
copy: {
main: {
files: [
{
expand: true,
cwd: 'node_modules/jquery/dist',
src: 'jquery.min.js',
dest: baseDir + '/js/dist'
},
],
},
},
// Run webpack (depending on development versus production)
webpack: {
dev: webpackConfig_dev(fileVersion),
prod: webpackConfig_prod(fileVersion),
},
// Enable live reloading of js/scss files
watch: {
css: {
files: [baseDir + '/styles/**/*.scss'],
tasks: ['sass']
},
js: {
files: [baseDir + '/js/src/**/*.js', '!' + baseDir + '/js/src/**/*.min.js'],
tasks: ['webpack:dev']
}
}
});
grunt.loadNpmTasks('grunt-sass');
grunt.loadNpmTasks('grunt-postcss');
grunt.loadNpmTasks('grunt-contrib-copy');
grunt.loadNpmTasks('grunt-webpack');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-clean');
// Available Grunt tasks
// development
grunt.registerTask('default', ['dev']);
grunt.registerTask('dev', ['clean', 'sass', 'postcss', 'copy', 'webpack:dev']);
// development (and watches for changes of .js and .css files)
grunt.registerTask('dev-watch', ['sass', 'postcss', 'webpack:dev', 'watch']);
// production ready
grunt.registerTask('prod', ['clean', 'sass', 'postcss', 'copy', 'webpack:prod']);
};
webpack.common.js
/**
* Webpack settings file :: Common (development & production)
*/
const ESLintPlugin = require('eslint-webpack-plugin');
const baseDir_js = "./js";
module.exports = {
// Define the "source" entry point for the application (or sub apps)
entry: {
main: baseDir_js + '/src/index.js',
admin: baseDir_js + '/src/admin.js',
sysAdmin: baseDir_js + '/src/sysAdmin.js',
},
// Let grunt know we have external libraries available
externals: {
jquery: 'jQuery',
google: 'google',
Stripe: 'Stripe',
},
module: {
rules: [
// process css files
{
test: /\.css$/,
use: [ 'style-loader', 'css-loader' ],
},
// process images/fonts -> base64
{
test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
type: 'asset/inline',
}
],
},
plugins: [new ESLintPlugin()],
};
webpack.dev.js
/**
* Webpack settings file :: Development
*/
// Import common settings
const {merge} = require('webpack-merge');
const common = require('./webpack.common.js');
const baseDir_js = "./js";
const path = require('path');
// Merge settings with "common"
module.exports = (fileVersion) => merge(common, {
mode: 'development',
// Use full source map
devtool: 'inline-source-map',
// Output entire code base to one file
output: {
filename: '[name].' + fileVersion + '.js',
// store in "dist/" directory
path: path.resolve(baseDir_js, 'dist'),
},
});
Does anybody have a working webpack.mix.js config for CKEditor5 32 on Laravel 8 (Laravel Mix 6 and Webpack 5) already? I have been banging my head to the wall for the past 8 hours and still could not manage to make it work.
Here is the console error I receive.
Before, when I was using Laravel Mix 5 and Webpack 4, this config solution seemed to be working.
But now all I get are a bunch of the same errors during npm compilation.
Config's snipped that worked for me
const CKEditorWebpackPlugin = require('#ckeditor/ckeditor5-dev-webpack-plugin');
const CKEditorStyles = require('#ckeditor/ckeditor5-dev-utils').styles;
//Includes SVGs and CSS files from "node_modules/ckeditor5-*" and any other custom directories
const CKEditorRegex = {
svg: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/, //If you have any custom plugins in your project with SVG icons, include their path in this regex as well.
css: /ckeditor5-[^/\\]+[/\\].+\.css$/,
};
//Exclude CKEditor regex from mix's default rules
Mix.listen('configReady', config => {
const rules = config.module.rules;
const targetSVG = (/(\.(png|jpe?g|gif|webp|avif)$|^((?!font).)*\.svg$)/).toString();
const targetFont = (/(\.(woff2?|ttf|eot|otf)$|font.*\.svg$)/).toString();
const targetCSS = (/\.p?css$/).toString();
rules.forEach(rule => {
let test = rule.test.toString();
if ([targetSVG, targetFont].includes(rule.test.toString())) {
rule.exclude = CKEditorRegex.svg;
} else if (test === targetCSS) {
rule.exclude = CKEditorRegex.css;
}
});
});
mix.webpackConfig({
plugins: [
new CKEditorWebpackPlugin({
language: 'en',
addMainLanguageTranslationsToAllAssets: true
}),
],
module: {
rules: [
{
test: CKEditorRegex.svg,
use: ['raw-loader']
},
{
test: CKEditorRegex.css,
use: [
{
loader: 'style-loader',
options: {
injectType: 'singletonStyleTag',
attributes: {
'data-cke': true
}
}
},
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: CKEditorStyles.getPostCssConfig({
themeImporter: {
themePath: require.resolve('#ckeditor/ckeditor5-theme-lark')
},
minify: true
})
}
}
]
}
]
}
});
Specs:
node v.16.11.1
npm v.8.0.0
Laravel v.8.77.1
package.json
"laravel-mix": "6.0.40",
"postcss-loader": "^6.2.1",
"raw-loader": "^4.0.1",
"sass": "^1.49.4",
"sass-loader": "^12.4.0",
"style-loader": "^2.0.0"
The Mix.listen() was deprecated and will go away in a future release. should replaced by mix.override().
Thanks #bakis.
This is the only working version after hours of searching. Exclude CKEditor regex from mix's default rules is the key neglected.
/** ckeditor 5 webpack config ****/
const CKEditorWebpackPlugin = require('#ckeditor/ckeditor5-dev-webpack-plugin');
const CKEditorStyles = require('#ckeditor/ckeditor5-dev-utils').styles;
//Includes SVGs and CSS files from "node_modules/ckeditor5-*" and any other custom directories
const CKEditorRegex = {
svg: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/, //If you have any custom plugins in your project with SVG icons, include their path in this regex as well.
css: /ckeditor5-[^/\\]+[/\\].+\.css$/,
};
mix.webpackConfig({
plugins: [
new CKEditorWebpackPlugin({
language: 'en',
addMainLanguageTranslationsToAllAssets: true
}),
],
module: {
rules: [
{
test: CKEditorRegex.svg,
use: ['raw-loader']
},
{
test: CKEditorRegex.css,
use: [
{
loader: 'style-loader',
options: {
injectType: 'singletonStyleTag',
attributes: {
'data-cke': true
}
}
},
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: CKEditorStyles.getPostCssConfig({
themeImporter: {
themePath: require.resolve('#ckeditor/ckeditor5-theme-lark')
},
minify: true
})
}
}
]
}
]
}
});
//Exclude CKEditor regex from mix's default rules
mix.override(config => {
const rules = config.module.rules;
const targetSVG = (/(\.(png|jpe?g|gif|webp|avif)$|^((?!font).)*\.svg$)/).toString();
const targetFont = (/(\.(woff2?|ttf|eot|otf)$|font.*\.svg$)/).toString();
const targetCSS = (/\.p?css$/).toString();
rules.forEach(rule => {
let test = rule.test.toString();
if ([targetSVG, targetFont].includes(rule.test.toString())) {
rule.exclude = CKEditorRegex.svg;
} else if (test === targetCSS) {
rule.exclude = CKEditorRegex.css;
}
});
});
I create a project base on with-ant-design-less and then try to add sass to project. I change the following files:
next.config.js:
/* eslint-disable */
const withSass = require("#zeit/next-sass");
const withLess = require("#zeit/next-less");
const lessToJS = require("less-vars-to-js");
const fs = require("fs");
const path = require("path");
// Where your antd-custom.less file lives
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, "./assets/antd-custom.less"), "utf8")
);
module.exports = withSass({
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: "[folder]_[local]___[hash:base64:5]",
},
...withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
},
webpack: (config, { isServer }) => {
if (isServer) {
const antStyles = /antd\/.*?\/style.*?/;
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;
},
}),
});
package.json
{
"name": "with-ant-design-less",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"#zeit/next-less": "^1.0.1",
"#zeit/next-sass": "^1.0.1",
"antd": "^3.5.4",
"babel-plugin-import": "^1.7.0",
"less": "3.0.4",
"less-vars-to-js": "1.3.0",
"next": "latest",
"null-loader": "2.0.0",
"react": "^16.7.0",
"sass": "^1.26.3",
"react-dom": "^16.7.0"
},
"license": "ISC",
"devDependencies": {
"#types/node": "^13.13.1",
"typescript": "^3.8.3"
}
}
but when I run the project I get the following error:
[ error ] ./pages/index.module.scss
To use Next.js' built-in Sass support, you first need to install `sass`.
Run `npm i sass` or `yarn add sass` inside your workspace.
Although I'm looking for better solution to setup the project because in this way all the style will be in one big chunk that cause performance issue.
Any idea? Thanks
next.config.js:
const withPlugins = require('next-compose-plugins');
const withCss = require('#zeit/next-css');
const withSass = require('#zeit/next-sass');
const withLess = require('#zeit/next-less');
const lessToJS = require('less-vars-to-js');
const fs = require('fs');
const path = require('path');
const lessThemeVariablesFilePath = './static/ant-theme-variables.less';
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, lessThemeVariablesFilePath), 'utf8'),
);
const lessNextConfig = {
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables,
},
webpack: (config, { isServer }) => {
if (isServer) {
const antStyles = /antd\/.*?\/style.*?/;
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;
},
};
const sassNextConfig = {
cssModules: true,
cssLoaderOptions: {
localIdentName: '[path]___[local]___[hash:base64:5]',
},
};
module.exports = withPlugins([
[withLess, lessNextConfig],
[withSass, sassNextConfig],
]);
babel config:
module.exports = {
presets: ['next/babel'],
plugins: [
['import', { libraryName: 'antd', style: true }],
],
};
I use sass, less and css. it depends on your requirement. and you can add your custom variables in an static file as I did.
hope be helpful.
So, for people who came here just for the basic addition, you can add antd to your nextjs app by installing antd
npm i antd
and then you can add the antd styles to your
_app.js file
after your global styles:
import 'antd/dist/antd.css'
I'm trying to import custom fonts using Gulp and Sass, but i can't figure out how.
For now, i've tried many things :
Create a mixin
#mixin font-face($font-family, $file-path, $font-weight, $font-style) {
#font-face {
font-family: $font-family;
src: url("#{$file-path}.eot");
src: url("#{$file-path}.eot?#iefix") format("embedded-opentype"),
url("#{$file-path}.woff") format("woff"),
url("#{$file-path}.ttf") format("truetype"),
url("#{$file-path}.svg##{$font-family}") format("svg");
font-weight: $font-weight;
font-style: $font-style;
}
// Chrome for Windows rendering fix: http://www.adtrak.co.uk/blog/font-face-chrome-rendering/
#media screen and (-webkit-min-device-pixel-ratio: 0) {
#font-face {
font-family: $font-family;
src: url("#{$file-path}.svg##{$font-family}") format("svg");
}
}
}
Then in my main scss file, i've included it like so
/* Include custom fonts */
#include font-face(
"Myfont-Regular",
"../../src/fonts/Myfont-Regu",
400,
normal
);
#include font-face(
"Myfont-Bold",
"../../src/fonts/Myfont-Bold",
700,
bold
);
#include font-face(
"Myfont-Black",
"../../src/fonts/Myfont-BlacExte",
900,
normal
);
/* End custom fonts include */
///Defining Font Family
$body-font-regular: "Myfont-Regular", Arial, Helvetica, sans-serif;
$body-font-bold: "Myfont-Bold", Arial, Helvetica, sans-serif;
$body-font-black: "Myfont-Black", Arial, Helvetica, sans-serif;
I think the main problem comes from my .gulpfile, but i can't find out where (i'm just starting using gulp, so i made it out of snippets i found). I've created a gulp task to copy the font folder but i'm not sure how to make it work. Here is my gulpfile :
"use strict";
/*global require*/
const autoprefixer = require("autoprefixer");
const babel = require("gulp-babel");
const browserSync = require("browser-sync");
const changed = require("gulp-changed");
const concat = require("gulp-concat");
const data = require("gulp-data");
const del = require("del");
const gulp = require("gulp");
const gulpif = require("gulp-if");
const imagemin = require("gulp-imagemin");
const path = require("path");
const plumber = require("gulp-plumber");
const postcss = require("gulp-postcss");
const pug = require("gulp-pug");
const runSequence = require("run-sequence");
const sass = require("gulp-sass");
const sourcemaps = require("gulp-sourcemaps");
const uglify = require("gulp-uglify");
/**
* List of options
*/
const options = {
uglifyJS: true,
sourceMaps: true,
useBabel: true
};
/*
* List of directories
*/
const paths = {
input: {
sass: "./src/sass/",
data: "./src/_data/",
js: "./src/js/",
images: "./src/img/",
fonts: "./src/fonts"
},
output: {
css: "./public/css/",
js: "./public/js/",
images: "./public/img/",
fonts: "./public/fonts"
},
public: "./public/"
};
/************************
* Gulp Tasks *
************************/
/**
* Concat all scripts and make sourcemap (optional)
* Scripts from vendor folder added first
*/
gulp.task("javascript", function() {
return gulp
.src([paths.input.js + "vendor/**/*.js", paths.input.js + "**/*.js"])
.pipe(plumber())
.pipe(gulpif(options.sourceMaps, sourcemaps.init()))
.pipe(
gulpif(
options.useBabel,
babel({
presets: ["#babel/preset-env"]
})
)
)
.pipe(concat("script.js"))
.pipe(gulpif(options.uglifyJS, uglify()))
.pipe(gulpif(options.sourceMaps, sourcemaps.write("../maps")))
.pipe(gulp.dest(paths.output.js))
.pipe(
browserSync.reload({
stream: true
})
);
});
/*
* Minify all images
*/
gulp.task("image-min", function() {
return gulp
.src(paths.input.images + "**/*.+(png|jpg|gif|svg|jpeg)")
.pipe(plumber())
.pipe(changed(paths.output.images))
.pipe(imagemin())
.pipe(gulp.dest(paths.output.images));
});
/**
* Compile .pug files and pass in data from json file
* Example: index.pug - index.pug.json
*/
gulp.task("pug", function() {
return gulp
.src("./src/*.pug")
.pipe(plumber())
.pipe(
data(function(file) {
const json = paths.input.data + path.basename(file.path) + ".json";
delete require.cache[require.resolve(json)];
return require(json);
})
)
.pipe(pug({ pretty: true }))
.pipe(gulp.dest(paths.public))
.pipe(
browserSync.reload({
stream: true
})
);
});
/**
* Removing public folder with it contents
*/
gulp.task("build-clean", function() {
return del(paths.public);
});
/**
* Recompile .pug files and live reload the browser
*/
gulp.task("rebuild", ["pug"], function() {
browserSync.reload();
});
/**
* Launch the browser-sync Server
*/
gulp.task("browser-sync", function() {
browserSync({
server: {
baseDir: paths.public
},
notify: false
});
});
/**
* Copy custom font folder
*/
gulp.task("copy", ["clean"], function() {
return gulp
.src(["src/fonts/*"], {
base: "src"
})
.pipe(gulp.dest("public"));
});
/**
* Task group for development
*/
gulp.task("develop", function() {
runSequence(
"build-clean",
["sass", "javascript", "image-min", "pug"],
"browser-sync"
);
});
/**
* Building distributive
*/
gulp.task("build-dist", function() {
runSequence("build-clean", ["sass", "javascript", "image-min", "pug"]);
});
/**
* Compile .scss files
* Autoprefixer
* Sourcemaps (optional)
*/
gulp.task("sass", function() {
return gulp
.src(paths.input.sass + "*.scss")
.pipe(plumber())
.pipe(gulpif(options.sourceMaps, sourcemaps.init()))
.pipe(
sass({
includePaths: [paths.input.sass],
outputStyle: "compressed"
})
)
.pipe(postcss([autoprefixer()]))
.pipe(gulpif(options.sourceMaps, sourcemaps.write("../maps")))
.pipe(gulp.dest(paths.output.css))
.pipe(
browserSync.reload({
stream: true
})
);
});
/**
* Watch files for changes
*/
gulp.task("watch", function() {
gulp.watch(paths.input.sass + "**/*.scss", ["sass"]);
gulp.watch(paths.input.js + "**/*.js", ["javascript"]);
gulp.watch(paths.input.images + "**/*", ["image-min"]);
gulp.watch(["./src/**/*.pug", "./src/**/*.json"], ["pug"]);
});
/**
* Shorthand for build-dist
*/
gulp.task("build", ["build-dist"]);
/**
* Default task for development, fast-start by 'gulp' command
*/
gulp.task("default", ["develop", "watch"]);
By the way, here is my project folder structure :