Как я могу запустить файл grunt в режиме просмотра, а также включить перезагрузку в реальном времени?

#node.js #sass #gruntjs #node-modules #pug-loader

#node.js #sass #gruntjs #узлы-модули #pug-загрузчик

Вопрос:

 require( 'time-grunt' )( grunt );
require( 'load-grunt-tasks' )( grunt );

grunt.loadNpmTasks('grunt-debug-inspector');
grunt.loadNpmTasks('grunt-contrib-watch');
grunt.loadNpmTasks('grunt-contrib-sass');
grunt.loadNpmTasks('grunt-contrib-pug');

grunt.config.init( {
    debug: {
        options: {
          open: true // do not open node-inspector in Chrome automatically
        }
      },
    concurrent: {
        develop: {
            tasks: [ 'nodemon', 'watch' ],
            options: {
                logConcurrentOutput: true
            }
        }
    },
    nodemon: {
        dev: {
            script: 'app.js',
            options: {
                watch: [ 'app', 'config' ],
                nodeArgs: [ '--debug' ],
                env: {
                    NODE_ENV: 'development',
                    DEBUG: '*, -express:*, -send, -compression, -body-parser:*, -puppeteer:*'
                }
            }
        }
    },
    sass: {
        options: {
            implementation: nodeSass
        },
        compile: {
            cwd: 'app/views/styles',
            dest: 'public/css',
            expand: true,
            outputStyle: 'compressed',
            src: '**/*.scss',
            ext: '.css',
            flatten: true,
            extDot: 'last'
        }
    },
    watch: {
        config: {
            files: [ 'config/*.json' ],
            tasks: [ 'client-config-file:create' ]
        },
        sass: {
            files: [ 'app/views/styles/**/*.scss', 'widget/**/*.scss', '!app/views/styles/component/_system_variables.scss' ],
            tasks: [ 'sass' ],
            options: {
                spawn: false,
                livereload: true
            }
        },
        jade: {
            files: [ 'app/views/**/*.pug' ],
            options: {
                spawn: false,
                livereload: true
            }
        },
        language: {
            files: [ 'app/views/**/*.pug', 'app/controllers/**/*.js', 'app/models/**/*.js', 'public/js/src/**/*.js' ],
            tasks: [ 'shell:translation', 'i18next' ]
        },
        js: {
            files: [ 'public/js/src/**/*.js', 'widget/**/*.js' ],
            tasks: [ 'js-dev' ],
            options: {
                spawn: false,
                livereload: true
            }
        }
    },
    shell: {
        translation: {
            command: [
                'cd locales',
                'gulp',
                'cd ..'
            ].join( 'amp;amp;' )
        },
        ie11polyfill: {
            command: [
                'mkdir -p public/js/build amp;amp; curl "https://polyfill.io/v3/polyfill.min.js?ua=ie/11.0.0amp;features=es2015,es2016,es2017,es2018,default-3.6,fetch,NodeList.prototype.forEach" -o "public/js/build/ie11-polyfill.min.js"',
                'cp -f node_modules/enketo-core/src/js/obscure-ie11-polyfills.js public/js/build/obscure-ie11-polyfills.js'
            ].join( 'amp;amp;' )
        },
        'clean-css': {
            command: 'rm -f public/css/*'
        },
        'clean-locales': {
            command: 'find locales -name "translation-combined.json" -delete amp;amp; rm -fr locales/??'
        },
        'clean-js': {
            command: 'rm -f public/js/build/* amp;amp; rm -f public/js/*.js amp;amp; rm -f public/temp-client-config.json'
        },
        rollup: {
            command: 'npx rollup --config'
        },
        babel: {
            command: bundles
                .map( bundle => `npx babel ${bundle} --out-file ${bundle.replace('-bundle.', '-ie11-temp-bundle.')}` )
                .join( 'amp;amp;' )
        },
        browserify: {
            command: bundles
                .map( bundle => `npx browserify node_modules/enketo-core/src/js/workarounds-ie11.js ${bundle.replace('-bundle.', '-ie11-temp-bundle.')} -o ${bundle.replace('-bundle.', '-ie11-bundle.')}` )
                .concat( [ 'rm -f public/js/build/*ie11-temp-bundle.js' ] )
                .join( 'amp;amp;' )
        }
    },
    jsbeautifier: {
        test: {
            src: JS_INCLUDE,
            options: {
                config: './.jsbeautifyrc',
                mode: 'VERIFY_ONLY'
            }
        },
        fix: {
            src: JS_INCLUDE,
            options: {
                config: './.jsbeautifyrc'
            }
        }
    },
    eslint: {
        all: JS_INCLUDE,
    },
    // test server JS
    mochaTest: {
        all: {
            options: {
                reporter: 'dot'
            },
            src: [ 'test/server/**/*.spec.js' ]
        },
        account: {
            src: [ 'test/server/account-*.spec.js' ]
        }
    },
    // test client JS
    karma: {
        options: {
            singleRun: true,
            reporters: [ 'dots' ],
            configFile: 'test/client/config/karma.conf.js'
        },
        headless: {
            browsers: [ 'ChromeHeadless' ]
        },
        browsers: {
            browsers: [ 'Chrome', 'ChromeCanary', 'Firefox', 'Opera' /*,'Safari'*/ ],
        }
    },
    terser: {
        options: {
            // https://github.com/enketo/enketo-express/issues/72
            keep_classnames: true,
        },
        all: {
            files: bundles
                .concat( bundles.map( bundle => bundle.replace( '-bundle.', '-ie11-bundle.' ) ) )
                .map( bundle => [ bundle.replace( '.js', '.min.js' ), [ bundle ] ] )
                .reduce( ( o, [ key, value ] ) => {
                    o[ key ] = value;
                    return o;
                }, {} )
        },
    },
    env: {
        develop: {
            NODE_ENV: 'develop'
        },
        test: {
            NODE_ENV: 'test'
        },
        production: {
            NODE_ENV: 'production'
        }
    },
    i18next: {
        locales: {
            cwd: 'locales/src/',
            expand: true,
            src: [ '*/' ],
            include: [ '**/translation.json', '**/translation-additions.json' ],
            rename( dest, src ) {
                return `${dest   src}translation-combined.json`;
            },
            dest: 'locales/build/'
        }
    }
} );

grunt.registerTask( 'client-config-file', 'Temporary client-config file', task => {
    const CLIENT_CONFIG_PATH = 'public/js/build/client-config.js';
    if ( task === 'create' ) {
        const config = require( './app/models/config-model' );
        grunt.file.write( CLIENT_CONFIG_PATH, `export default ${JSON.stringify( config.client )};` );
        grunt.log.writeln( `File ${CLIENT_CONFIG_PATH} created` );
    } else if ( task === 'remove' ) {
        grunt.file.delete( CLIENT_CONFIG_PATH );
        grunt.log.writeln( `File ${CLIENT_CONFIG_PATH} removed` );
    }
} );

grunt.registerTask( 'system-sass-variables', 'Creating _system_variables.scss', () => {
    const SYSTEM_SASS_VARIABLES_PATH = 'app/views/styles/component/_system_variables.scss';
    const config = require( './app/models/config-model' );
    grunt.file.write( SYSTEM_SASS_VARIABLES_PATH, `$base-path: "${config.server[ 'base path' ]}";` );
    grunt.log.writeln( `File ${SYSTEM_SASS_VARIABLES_PATH} created` );
} );

grunt.registerTask( 'widgets', 'generate widget reference files', () => {
    const WIDGETS_JS_LOC = 'public/js/build/';
    const WIDGETS_JS = `${WIDGETS_JS_LOC}widgets.js`;
    const WIDGETS_SASS_LOC = 'app/views/styles/component/';
    const WIDGETS_SASS = `${WIDGETS_SASS_LOC}_widgets.scss`;
    const PRE = '// This file is automatically generated with `grunt widgets`nn';
    const widgets = require( './app/models/config-model' ).server.widgets;
    const coreWidgets = require( './public/js/src/module/core-widgets' );
    const paths = Object.keys( widgets ).map( key => coreWidgets[ widgets[ key ] ] || widgets[ key ] );
    let num = 0;
    let content = PRE   paths.map( p => {
        if ( grunt.file.exists( WIDGETS_JS_LOC, `${p}.js` ) ) {
            num  ;
            return `import w${num} from '${p}';`;
        } else {
            return `//${p} not found`;
        }
    } ).join( 'n' )   `nnexport default [${[...Array(num).keys()].map(n => 'w' (n 1)).join(', ')}];`;
    grunt.file.write( WIDGETS_JS, content );
    grunt.log.writeln( `File ${WIDGETS_JS} created` );
    content = `${PRE  
paths.map( p => {
    p = path.join( '../', p );
    return grunt.file.exists( WIDGETS_SASS_LOC, `${p}.scss` ) ? `@import "${p}"` : `//${p} not found`;
} ).join( ';n' )};`;
    grunt.file.write( WIDGETS_SASS, content );
    grunt.log.writeln( `File ${WIDGETS_SASS} created` );
} );


grunt.registerTask('w', ['watch']);
grunt.registerTask( 'default', [ 'locales', 'widgets', 'css', 'js-ie11', 'terser' ] );
grunt.registerTask( 'locales', [ 'shell:clean-locales', 'i18next' ] );
grunt.registerTask( 'js', [ 'shell:clean-js', 'client-config-file:create', 'widgets', 'shell:rollup' ] );
grunt.registerTask( 'js-dev', [ 'js' ] );
grunt.registerTask( 'js-ie11', [ 'js', 'shell:ie11polyfill', 'shell:babel', 'shell:browserify' ] );
grunt.registerTask( 'css', [ 'shell:clean-css', 'system-sass-variables:create', 'sass' ] );
grunt.registerTask( 'test', [ 'env:test', 'js', 'css', 'mochaTest:all', 'karma:headless', 'jsbeautifier:test', 'eslint' ] );
grunt.registerTask( 'test-browser', [ 'env:test', 'css', 'client-config-file:create', 'karma:browsers' ] );
grunt.registerTask( 'develop', [ 'env:develop', 'i18next', 'js-dev', 'css', 'concurrent:develop' ] );
grunt.registerTask( 'develop-ie11', [ 'env:develop', 'i18next', 'js-ie11', 'css', 'concurrent:develop' ] );
grunt.registerTask( 'test-and-build', [ 'env:test', 'mochaTest:all', 'karma:headless', 'env:production', 'default' ] );};
 

Когда я запускаю grunt watch, он продолжает работать только в режиме ожидания и застрял там? Но я хочу, чтобы grunt watch работал нормально, поскольку это позволит мне работать в режиме разработки. Теперь в моем проекте происходит то, что мне приходится снова и снова запускать команду grunt, чтобы создать проект, чтобы увидеть небольшие изменения, и это занимает слишком много времени? Я новичок в grunt. Я хочу работать в режиме быстрой / разработки и хочу, чтобы в файле grunt была включена функция горячей перезагрузки, а также просмотр grunt. Пожалуйста, предложите какое-нибудь решение.